ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
Panel.c File Reference
#include <assert.h>
#include "Panel.h"
#include "../Assets/resize.png.h"

Go to the source code of this file.

Macros

#define _Class   _Panel
 

Functions

Class * _Panel (void)
 
static bool acceptsKeyResponder (const View *self)
 
static void applyStyle (View *self, const Style *style)
 
static void awakeWithDictionary (View *self, const Dictionary *dictionary)
 
static bool captureEvent (Control *self, const SDL_Event *event)
 
static SDL_Size contentSize (const Panel *self)
 
static void dealloc (Object *self)
 
static void destroy (Class *clazz)
 
static View * init (View *self)
 
static void initialize (Class *clazz)
 
static Panel * initWithFrame (Panel *self, const SDL_Rect *frame)
 
static void layoutSubviews (View *self)
 

Variables

static Image * _resize
 

Macro Definition Documentation

◆ _Class

#define _Class   _Panel

Definition at line 32 of file Panel.c.

Function Documentation

◆ _Panel()

Class * _Panel ( void  )

Definition at line 301 of file Panel.c.

301 {
302 static Class *clazz;
303 static Once once;
304
305 do_once(&once, {
306 clazz = _initialize(&(const ClassDef) {
307 .name = "Panel",
308 .superclass = _Control(),
309 .instanceSize = sizeof(Panel),
310 .interfaceSize = sizeof(PanelInterface),
311 .initialize = initialize,
312 .destroy = destroy,
313 });
314 });
315
316 return clazz;
317}
Class * _Control(void)
Definition Control.c:414
static void destroy(Class *clazz)
Definition Panel.c:293
static void initialize(Class *clazz)
Definition Panel.c:272
Draggable and resizable container Views.
Definition Panel.h:47

◆ acceptsKeyResponder()

static bool acceptsKeyResponder ( const View *  self)
static
See also
View::acceptsKeyResponder(View *)

Definition at line 56 of file Panel.c.

56 {
57 return false;
58}

◆ applyStyle()

static void applyStyle ( View *  self,
const Style *  style 
)
static
See also
View::applyStyle(View *, const Style *)

Definition at line 63 of file Panel.c.

63 {
64
65 super(View, self, applyStyle, style);
66
67 Panel *this = (Panel *) self;
68
69 const Inlet inlets[] = MakeInlets(
70 MakeInlet("draggable", InletTypeBool, &this->isDraggable, NULL),
71 MakeInlet("resizable", InletTypeBool, &this->isResizable, NULL)
72 );
73
74 $(self, bind, inlets, (Dictionary *) style->attributes);
75}
static void applyStyle(View *self, const Style *style)
Definition Panel.c:63
@ InletTypeBool
Definition View+JSON.h:46
#define MakeInlets(...)
Creates a null-termianted array of Inlets.
Definition View+JSON.h:215
#define MakeInlet(name, type, dest, data)
Creates an Inlet with the specified parameters.
Definition View+JSON.h:210
Inlets enable inbound data binding of View attributes through JSON.
Definition View+JSON.h:149
Dictionary * attributes
Definition Style.h:59
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition View.h:225

◆ awakeWithDictionary()

static void awakeWithDictionary ( View *  self,
const Dictionary *  dictionary 
)
static
See also
View::awakeWithDictionary(View *, const Dictionary *)

Definition at line 80 of file Panel.c.

80 {
81
82 super(View, self, awakeWithDictionary, dictionary);
83
84 Panel *this = (Panel *) self;
85
86 const Inlet inlets[] = MakeInlets(
87 MakeInlet("accessoryView", InletTypeView, &this->accessoryView, NULL),
88 MakeInlet("contentView", InletTypeView, &this->contentView, NULL),
89 MakeInlet("stackView", InletTypeView, &this->stackView, NULL)
90 );
91
92 $(self, bind, inlets, dictionary);
93}
static void awakeWithDictionary(View *self, const Dictionary *dictionary)
Definition Panel.c:80
@ InletTypeView
Definition View+JSON.h:133

◆ captureEvent()

static bool captureEvent ( Control *  self,
const SDL_Event *  event 
)
static
See also
Control::captureEvent(Control *, const SDL_Event *)

Definition at line 131 of file Panel.c.

131 {
132
133 Panel *this = (Panel *) self;
134
135 if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
136 if ($((View *) this->resizeHandle, didReceiveEvent, event)) {
137 if (this->isResizable && !this->isDragging) {
138 this->isResizing = true;
139 }
140 return true;
141 }
142 }
143
144 if (event->type == SDL_EVENT_MOUSE_MOTION) {
145
146 if (event->motion.state & SDL_BUTTON_LEFT) {
148
149 if (this->isResizing || this->isDraggable) {
150
151 // Motion is reported in points, which are fractional on high-density
152 // displays. Carry the sub-point remainder between events so the integer
153 // deltas applied to the frame sum exactly to the cursor's movement,
154 // rather than truncating away a fraction each event and drifting behind.
155 this->gestureResidual.x += event->motion.xrel;
156 this->gestureResidual.y += event->motion.yrel;
157
158 const int dx = (int) this->gestureResidual.x;
159 const int dy = (int) this->gestureResidual.y;
160
161 this->gestureResidual.x -= dx;
162 this->gestureResidual.y -= dy;
163
164 if (this->isResizing) {
165 SDL_Size size = $((View *) self, size);
166
167 size.w += dx;
168 size.h += dy;
169
170 $((View *) self, resize, &size);
171
172 } else {
173 this->isDragging = true;
174
175 self->view.frame.x += dx;
176 self->view.frame.y += dy;
177
178 // Direct frame mutation outside of layout: refresh the render frame caches so
179 // hit-testing for the remainder of this event batch sees the moved Panel.
181 }
182
183 return true;
184 }
185 } else {
186 self->state &= ~ControlStateHighlighted;
187 this->isResizing = this->isDragging = false;
188 this->gestureResidual.x = this->gestureResidual.y = 0.f;
189 }
190 }
191
192 return super(Control, self, captureEvent, event);
193}
@ ControlStateHighlighted
Definition Control.h:67
static SDL_Size size(const Image *self)
Definition Image.c:416
static bool captureEvent(Control *self, const SDL_Event *event)
Definition Panel.c:131
static void resize(View *self, const SDL_Size *size)
Definition View.c:1708
void MVC_InvalidateRenderFrames(void)
Invalidates every View's cached View::renderFrame and View::clippingFrame.
Definition View.c:46
static bool didReceiveEvent(const View *self, const SDL_Event *event)
Definition View.c:726
Controls are Views which capture and respond to events.
Definition Control.h:83
unsigned int state
The bit mask of ControlState.
Definition Control.h:117
View view
The superclass.
Definition Control.h:88
SDL_Rect frame
The frame, relative to the superview.
Definition View.h:301

◆ contentSize()

static SDL_Size contentSize ( const Panel *  self)
static

Definition at line 201 of file Panel.c.

201 {
202
203 const View *accessoryView = (View *) self->accessoryView;
204 const View *contentView = (View *) self->contentView;
205
206 SDL_Size size = $(contentView, sizeThatContains);
207
208 if (accessoryView->visibility != ViewVisibilityHidden) {
209 const SDL_Size accessorySize = $(accessoryView, sizeThatContains);
210 size.h -= accessorySize.h + self->stackView->spacing;
211 }
212
213 return size;
214}
static SDL_Size sizeThatContains(const View *self)
Definition View.c:1886
@ ViewVisibilityHidden
Definition View.h:122
StackView * accessoryView
The optional accessories container.
Definition Panel.h:64
StackView * contentView
The internal container.
Definition Panel.h:69
int spacing
The subview spacing.
Definition StackView.h:105

◆ dealloc()

static void dealloc ( Object *  self)
static
See also
Object::dealloc(Object *)

Definition at line 39 of file Panel.c.

39 {
40
41 Panel *this = (Panel *) self;
42
43 release(this->accessoryView);
44 release(this->contentView);
45 release(this->resizeHandle);
46 release(this->stackView);
47
48 super(Object, self, dealloc);
49}
static void dealloc(Object *self)
Definition Panel.c:39

◆ destroy()

static void destroy ( Class *  clazz)
static
See also
Class::destroy(Class *)

Definition at line 293 of file Panel.c.

293 {
294 release(_resize);
295}
static Image * _resize
Definition Panel.c:30

◆ init()

static View * init ( View *  self)
static
See also
View::init(View *)

Definition at line 98 of file Panel.c.

98 {
99 return (View *) $((Panel *) self, initWithFrame, NULL);
100}
static Panel * initWithFrame(Panel *self, const SDL_Rect *frame)
Definition Panel.c:220

◆ initialize()

static void initialize ( Class *  clazz)
static
See also
Class::initialize(Class *)

Definition at line 272 of file Panel.c.

272 {
273
274 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
275
276 ((ViewInterface *) clazz->interface)->acceptsKeyResponder = acceptsKeyResponder;
277 ((ViewInterface *) clazz->interface)->applyStyle = applyStyle;
278 ((ViewInterface *) clazz->interface)->awakeWithDictionary = awakeWithDictionary;
279 ((ViewInterface *) clazz->interface)->init = init;
280 ((ViewInterface *) clazz->interface)->layoutSubviews = layoutSubviews;
281
282 ((ControlInterface *) clazz->interface)->captureEvent = captureEvent;
283
284 ((PanelInterface *) clazz->interface)->contentSize = contentSize;
285 ((PanelInterface *) clazz->interface)->initWithFrame = initWithFrame;
286
287 _resize = $(alloc(Image), initWithBytes, resize_png, resize_png_len - 1, 1.f);
288}
static Image * initWithBytes(Image *self, const uint8_t *bytes, size_t length, float pixelDensity)
Definition Image.c:118
static SDL_Size contentSize(const Panel *self)
Definition Panel.c:201
static bool acceptsKeyResponder(const View *self)
Definition Panel.c:56
static View * init(View *self)
Definition Panel.c:98
static void layoutSubviews(View *self)
Definition Panel.c:105
Image loading.
Definition Image.h:41
layoutSubviews(View *self)
Arranges this View's immediate subviews within its (already final) frame.
Definition Box.c:74

◆ initWithFrame()

static Panel * initWithFrame ( Panel *  self,
const SDL_Rect *  frame 
)
static

Definition at line 220 of file Panel.c.

220 {
221
222 self = (Panel *) super(Control, self, initWithFrame, frame);
223 if (self) {
224 View *this = (View *) self;
225
226 self->isDraggable = true;
227 self->isResizable = true;
228
229 self->stackView = $(alloc(StackView), initWithFrame, NULL);
230 assert(self->stackView);
231
232 $(this, addSubview, (View *) self->stackView);
233
234 self->contentView = $(alloc(StackView), initWithFrame, NULL);
235 assert(self->contentView);
236
237 $((View *) self->contentView, addClassName, "contentView");
238 $((View *) self->contentView, addClassName, "container");
239
241
242 $((View *) self->stackView, addSubview, (View *) self->contentView);
243
244 self->accessoryView = $(alloc(StackView), initWithFrame, NULL);
245 assert(self->accessoryView);
246
247 $((View *) self->accessoryView, addClassName, "accessoryView");
248 $((View *) self->accessoryView, addClassName, "container");
249
250
251 $((View *) self->stackView, addSubview, (View *) self->accessoryView);
252
253 self->resizeHandle = $(alloc(ImageView), initWithImage, _resize);
254 assert(self->resizeHandle);
255
256 $((View *) self->resizeHandle, addClassName, "resizeHandle");
257
258 self->resizeHandle->view.frame.w = DEFAULT_PANEL_RESIZE_HANDLE_SIZE;
259 self->resizeHandle->view.frame.h = DEFAULT_PANEL_RESIZE_HANDLE_SIZE;
260
261 $((View *) self, addSubview, (View *) self->resizeHandle);
262 }
263
264 return self;
265}
static AtlasImage * initWithImage(AtlasImage *self, ImageAtlas *atlas, Image *image)
Definition AtlasImage.c:32
static void addSubview(View *self, View *subview)
Definition PageView.c:49
#define DEFAULT_PANEL_RESIZE_HANDLE_SIZE
Definition Panel.h:35
static void addClassName(View *self, const char *className)
Definition View.c:183
@ ViewAutoresizingWidth
Definition View.h:91
ImageViews render an Image in the context of a View hierarchy.
Definition ImageView.h:45
View view
The superclass.
Definition ImageView.h:50
bool isResizable
If true, this Panel may be resized by the user.
Definition Panel.h:86
bool isDraggable
If true, this Panel may be repositioned by the user.
Definition Panel.h:75
StackViews are containers that manage the arrangement of their subviews.
Definition StackView.h:68
View view
The superclass.
Definition StackView.h:73
int autoresizingMask
The ViewAutoresizing bitmask.
Definition View.h:248

◆ layoutSubviews()

static void layoutSubviews ( View *  self)
static
See also
View::layoutSubviews(View *)

Definition at line 105 of file Panel.c.

105 {
106
107 const Panel *this = (Panel *) self;
108
109 const SDL_Size size = $(this, contentSize);
110
111 View *contentView = (View *) this->contentView;
112
113 $(contentView, layoutWithSize, &size);
114
115 super(View, self, layoutSubviews);
116
117 View *resizeHandle = (View *) this->resizeHandle;
118
119 resizeHandle->frame.x = self->frame.w - resizeHandle->frame.w;
120 resizeHandle->frame.y = self->frame.h - resizeHandle->frame.h;
121
122 $(resizeHandle, setVisibility,
123 this->isResizable ? ViewVisibilityVisible : ViewVisibilityHidden);
124}
static void setVisibility(View *self, ViewVisibility visibility)
Definition View.c:1834
static void layoutWithSize(View *self, const SDL_Size *size)
Definition View.c:1267
@ ViewVisibilityVisible
Definition View.h:121

Variable Documentation

◆ _resize

Image* _resize
static

Definition at line 30 of file Panel.c.