ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
WindowController Struct Reference

A WindowController manages a ViewController and its descendants within an SDL_Window. More...

#include <WindowController.h>

Inheritance diagram for WindowController:

Public Member Functions

Class * _WindowController (void)
 The WindowController archetype.
 
void debug (WindowController *self)
 Debugs the current frame.
 
WindowController * initWithDevice (WindowController *self, RenderDevice *device)
 Initializes this WindowController with the given RenderDevice.
 
View * keyResponder (const WindowController *self)
 
Array * keyResponders (const WindowController *self)
 
View * nextKeyResponder (const WindowController *self, View *keyResponder)
 Finds the next available keyResponder from the given keyResponder.
 
View * previousKeyResponder (const WindowController *self, View *keyResponder)
 Finds the previous available keyResponder from the given keyResponder.
 
void render (WindowController *self)
 Renders the ViewController's View into the RenderDevice's current frame.
 
void renderTo (WindowController *self, CommandBuffer *commands, Framebuffer *framebuffer)
 Renders the ViewController's View into the given Framebuffer.
 
void respondToEvent (WindowController *self, const SDL_Event *event)
 Responds to the given event.
 
void setTheme (WindowController *self, Theme *theme)
 Sets this WindowController's Theme.
 
void setViewController (WindowController *self, ViewController *viewController)
 Sets this WindowController's ViewController.
 
void setWindow (WindowController *self, SDL_Window *window)
 Sets this WindowController's window.
 
void toggleDebugger (WindowController *self)
 Toggles the debugger tools.
 
View * touchResponder (const WindowController *self)
 
View * touchResponder (const WindowController *self, const SDL_Event *event)
 
WindowController * windowController (SDL_Window *window)
 

Data Fields

DebugViewController * debugViewController
 The DebugViewController.
 
Object object
 The superclass.
 
Renderer * renderer
 The Renderer.
 
Theme * theme
 The Theme.
 
ViewController * viewController
 The ViewController.
 
SDL_Window * window
 The window.
 

Protected Attributes

WindowControllerInterface * interface [0]
 The interface type.
 

Detailed Description

A WindowController manages a ViewController and its descendants within an SDL_Window.

Definition at line 45 of file WindowController.h.

Member Function Documentation

◆ _WindowController()

Class * _WindowController ( void  )

The WindowController archetype.

Returns
The WindowController Class.

Definition at line 578 of file WindowController.c.

578 {
579 static Class *clazz;
580 static Once once;
581
582 do_once(&once, {
583 clazz = _initialize(&(const ClassDef) {
584 .name = "WindowController",
585 .superclass = _Object(),
586 .instanceSize = sizeof(WindowController),
587 .interfaceSize = sizeof(WindowControllerInterface),
588 .initialize = initialize,
589 });
590 });
591
592 return clazz;
593}
static void initialize(Class *clazz)
Definition AtlasImage.c:74
A WindowController manages a ViewController and its descendants within an SDL_Window.

◆ debug()

void debug ( WindowController *  self)

Debugs the current frame.

Parameters
selfThe WindowController.

Definition at line 77 of file WindowController.c.

77 {
78
79 if (self->viewController && self->debugViewController) {
80
82
83 float mx, my;
84 SDL_GetMouseState(&mx, &my);
85 SDL_Point point = MakePoint(mx, my);
86
87 View *view = $(self->viewController->view, hitTest, &point);
88 if (view) {
89 $(self->debugViewController, debug, view, self->renderer);
90 }
91
94
96
98 }
99}
static void layoutIfNeeded(View *self)
Definition View.c:1174
static void draw(View *self, Renderer *renderer)
Definition View.c:778
void MVC_InvalidateRenderFrames(void)
Invalidates every View's cached View::renderFrame and View::clippingFrame.
Definition View.c:46
static View * hitTest(const View *self, const SDL_Point *point)
Definition View.c:1012
static void applyThemeIfNeeded(View *self, const Theme *theme)
Definition View.c:369
A ViewController manages a View and its descendants.
View * view
The main view.
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition View.h:225
ViewController * viewController
The ViewController.
Theme * theme
The Theme.
Renderer * renderer
The Renderer.
DebugViewController * debugViewController
The DebugViewController.
void debug(WindowController *self)
Debugs the current frame.

◆ initWithDevice()

WindowController * initWithDevice ( WindowController *  self,
RenderDevice *  device 
)

Initializes this WindowController with the given RenderDevice.

Parameters
selfThe WindowController.
deviceThe RenderDevice.
Returns
The initialized WindowController, or NULL on error.

Definition at line 135 of file WindowController.c.

135 {
136
137 assert(device);
138
139 self = (WindowController *) super(Object, self, init);
140 if (self) {
141 self->renderer = $(alloc(Renderer), initWithDevice, device);
142 assert(self->renderer);
143
144 $(self, setWindow, device->window);
145 $(self, setViewController, NULL);
146 $(self, setTheme, NULL);
147
150 $(self->theme, renderDeviceDidReset);
151 }
152
153 return self;
154}
static View * init(View *self)
Definition Box.c:67
static void renderDeviceDidReset(Renderer *self)
Definition Renderer.c:705
Renderer extends Object with ObjectivelyMVC's UI rendering layer.
Definition Renderer.h:75
void setWindow(WindowController *self, SDL_Window *window)
Sets this WindowController's window.
WindowController * initWithDevice(WindowController *self, RenderDevice *device)
Initializes this WindowController with the given RenderDevice.
void setViewController(WindowController *self, ViewController *viewController)
Sets this WindowController's ViewController.
void setTheme(WindowController *self, Theme *theme)
Sets this WindowController's Theme.

◆ keyResponder()

View * keyResponder ( const WindowController *  self)
Parameters
selfThe WindowController.
Returns
The key responder or NULL.

Definition at line 105 of file WindowController.c.

105 {
106 return SDL_GetPointerProperty(SDL_GetWindowProperties(self->window), "keyResponder", NULL);
107}
SDL_Window * window
The window.

◆ keyResponders()

Array * keyResponders ( const WindowController *  self)
Parameters
selfThe WindowController.
Returns
An Array of all first responders in the WindowController's View hierarchy.

Definition at line 123 of file WindowController.c.

123 {
124
125 Array *array = (Array *) $(alloc(Array), init);
127
128 return array;
129}
static void enumerateDescendants(const View *self, ViewEnumerator enumerator, ident data)
Definition View.c:866
static void enumerateKeyResponders(View *view, ident data)
ViewEnumerator for finding the next key responder.

◆ nextKeyResponder()

View * nextKeyResponder ( const WindowController *  self,
View *  keyResponder 
)

Finds the next available keyResponder from the given keyResponder.

Parameters
selfThe WindowController.
keyResponderThe current keyResponder.
Returns
The next keyResponder, or NULL.

Definition at line 196 of file WindowController.c.

196 {
197
198 View *next = NULL;
199
200 Array *array = $(self, keyResponders);
201
202 if (array->count) {
203 if (keyResponder && $(array, containsObject, keyResponder)) {
204 const ssize_t index = $(array, indexOfObject, keyResponder);
205 next = $(array, objectAtIndex, (index + 1) % array->count);
206 } else {
207 next = $(array, firstObject);
208 }
209 }
210
211 release(array);
212 return next;
213}
Array * keyResponders(const WindowController *self)
View * keyResponder(const WindowController *self)

◆ previousKeyResponder()

View * previousKeyResponder ( const WindowController *  self,
View *  keyResponder 
)

Finds the previous available keyResponder from the given keyResponder.

Parameters
selfThe WindowController.
keyResponderThe current keyResponder.
Returns
The previous keyResponder, or NULL.

Definition at line 219 of file WindowController.c.

219 {
220
221 View *prev = NULL;
222
223 Array *array = $(self, keyResponders);
224
225 if (array->count) {
226 if (keyResponder && $(array, containsObject, keyResponder)) {
227 const ssize_t index = $(array, indexOfObject, keyResponder);
228 prev = $(array, objectAtIndex, (index + array->count - 1) % array->count);
229 } else {
230 prev = $(array, firstObject);
231 }
232 }
233
234 release(array);
235 return prev;
236}

◆ render()

void render ( WindowController *  self)

Renders the ViewController's View into the RenderDevice's current frame.

Convenience over renderTo for the common case of rendering the UI into the device's own current command buffer and framebuffer. Equivalent to $(self, renderTo, device->commands, device->framebuffer).

Parameters
selfThe WindowController.

Definition at line 160 of file WindowController.c.

160 {
161
162 assert(self->renderer);
163
164 const RenderDevice *device = self->renderer->device;
165 $(self, renderTo, device->commands, device->framebuffer);
166}
RenderDevice * device
The backing RenderDevice.
Definition Renderer.h:97
void renderTo(WindowController *self, CommandBuffer *commands, Framebuffer *framebuffer)
Renders the ViewController's View into the given Framebuffer.

◆ renderTo()

void renderTo ( WindowController *  self,
CommandBuffer *  commands,
Framebuffer *  framebuffer 
)

Renders the ViewController's View into the given Framebuffer.

The caller owns commands and is responsible for submitting it after this returns. The UI is composited over whatever is already in the Framebuffer's color texture (SDL_GPU_LOADOP_LOAD), so render your scene into the Framebuffer first.

Parameters
selfThe WindowController.
commandsThe frame's CommandBuffer.
framebufferThe Framebuffer to render the UI into.

Definition at line 172 of file WindowController.c.

172 {
173
174 assert(self->renderer);
175 assert(commands);
176 assert(framebuffer);
177
178 $(self->renderer, beginFrameWith, commands, framebuffer);
179
182
184
185 $(self->viewController->view, draw, self->renderer);
186
187 $(self, debug);
188
189 $(self->renderer, endFrame);
190}
static void endFrame(Renderer *self)
Definition Renderer.c:555
static void beginFrameWith(Renderer *self, CommandBuffer *commands, Framebuffer *framebuffer)
Definition Renderer.c:109

◆ respondToEvent()

void respondToEvent ( WindowController *  self,
const SDL_Event *  event 
)

Responds to the given event.

Remarks
Exposure MUST NOT reset render device resources. It fires on every frame on some platforms, where resetting leaks a generation of GPU resources per frame. Only the view hierarchy's resources depend on the window, through its pixel density, so only a change in pixel density resets them. The renderer's own resources are created with the device.
Window events for another window MUST be ignored, or a window being torn down releases the resources of the controller that replaced it.
Parameters
selfThe WindowController.
eventThe event.
Remarks
Your application should call this method for each event that the View hierarchy is expected to respond to. The event will be dispatched to WindowController::keyResponder, which is the first of:
By default, the event is passed up the View hierarchy by View::respondToEvent. Subclasses of View, such as Control, may stop event propagation if an event has been captured.

Definition at line 248 of file WindowController.c.

248 {
249
250 if (event->type >= SDL_EVENT_WINDOW_FIRST && event->type <= SDL_EVENT_WINDOW_LAST) {
251 if (event->window.windowID != SDL_GetWindowID(self->window)) {
252 return;
253 }
254 }
255
256 SDL_SetPointerProperty(SDL_GetWindowProperties(self->window), "event", (ident) event);
257
258 switch (event->type) {
259 case SDL_EVENT_WINDOW_MOVED:
260 case SDL_EVENT_WINDOW_RESIZED:
261 case SDL_EVENT_WINDOW_MAXIMIZED:
262 case SDL_EVENT_WINDOW_RESTORED:
263 case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED:
264 $(self, setWindow, self->window);
265 break;
266 case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
267 case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
268 case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: {
269 $(self, setWindow, self->window);
270
273 $(self->viewController->view, updateBindings, NULL);
275 $(self->theme, renderDeviceDidReset);
276
277 if (self->debugViewController) {
282 }
283 }
284 break;
285 case SDL_EVENT_WINDOW_DESTROYED:
286 case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
290 break;
291 default:
292 break;
293 }
294
295 if (event->type == SDL_EVENT_MOUSE_MOTION) {
297 }
298
300
301 View *touchTarget = $(self, touchTarget, event);
302
303 switch (event->type) {
304 case SDL_EVENT_KEY_UP:
305 case SDL_EVENT_KEY_DOWN:
306 case SDL_EVENT_TEXT_INPUT:
307 if (keyResponder) {
308 $(keyResponder, respondToEvent, event);
309 } else {
310 $(self->viewController, respondToEvent, event);
311 }
312 break;
313 case SDL_EVENT_MOUSE_BUTTON_DOWN:
314 if (touchTarget) {
316 $(touchTarget, respondToEvent, event);
317 } else if (touchResponder) {
320 } else {
321 $(self->viewController, respondToEvent, event);
322 }
323
327 }
328 break;
329 case SDL_EVENT_MOUSE_BUTTON_UP:
330 if (touchResponder) {
332 } else if (touchTarget) {
333 $(touchTarget, respondToEvent, event);
334 } else {
335 $(self->viewController, respondToEvent, event);
336 }
337 break;
338 case SDL_EVENT_MOUSE_MOTION:
339 case SDL_EVENT_MOUSE_WHEEL:
340 if (touchResponder) {
342 } else if (touchTarget) {
343 $(touchTarget, respondToEvent, event);
344 } else {
345 $(self->viewController, respondToEvent, event);
346 }
347 break;
348 default:
349 $(self->viewController, respondToEvent, event);
350 break;
351 }
352
353 if (event->type == SDL_EVENT_KEY_DOWN) {
354 if (event->key.key == SDLK_TAB || event->key.key == SDLK_KP_TAB) {
355
356 View *current = $(self, keyResponder);
357
358 // An editing TextView that is still the key responder kept Tab to auto-complete
359 const bool consumed = current && current == keyResponder &&
360 $((Object *) current, isKindOfClass, _TextView()) &&
361 ((TextView *) current)->isEditable &&
362 !$((Control *) current, isDisabled);
363
364 if (!consumed) {
365 if (event->key.mod & SDL_KMOD_SHIFT) {
367 } else {
369 }
370
371 if (keyResponder) {
373 }
374 }
375 }
376
377 if (event->key.key == SDLK_D) {
378 if (event->key.mod & SDL_KMOD_CTRL) {
379 $(self, toggleDebugger);
380 }
381 }
382 }
383
384 SDL_SetPointerProperty(SDL_GetWindowProperties(self->window), "event", NULL);
385}
static void becomeKeyResponder(View *self)
Definition Control.c:132
static void resignKeyResponder(View *self)
Definition Control.c:265
static bool isDisabled(const Control *self)
Definition Control.c:334
static void updateBindings(View *self, ident data)
static void renderDeviceWillReset(ImageAtlas *self)
Definition ImageAtlas.c:281
Class * _TextView(void)
Definition TextView.c:629
static void enumerateVisible(View *self, ViewEnumerator enumerator, ident data)
Definition View.c:931
static void becomeTouchResponder(View *self)
Definition View.c:511
static void resignTouchResponder(View *self)
Definition View.c:1692
static View * touchTarget(const WindowController *self, const SDL_Event *event)
static void mouseMotion_enumerate(View *view, ident data)
ViewEnumerator for SDL_EVENT_MOUSE_MOTION.
Controls are Views which capture and respond to events.
Definition Control.h:83
A Control for presenting and capturing user-provied Text.
Definition TextView.h:93
View * touchResponder(const WindowController *self, const SDL_Event *event)
View * previousKeyResponder(const WindowController *self, View *keyResponder)
Finds the previous available keyResponder from the given keyResponder.
void toggleDebugger(WindowController *self)
Toggles the debugger tools.
View * nextKeyResponder(const WindowController *self, View *keyResponder)
Finds the next available keyResponder from the given keyResponder.
void respondToEvent(WindowController *self, const SDL_Event *event)
Responds to the given event.

◆ setTheme()

void setTheme ( WindowController *  self,
Theme *  theme 
)

Sets this WindowController's Theme.

Parameters
selfThe WindowController.
themeThe Theme.

Definition at line 391 of file WindowController.c.

391 {
392
393 if (self->theme != theme || self->theme == NULL) {
394
395 release(self->theme);
396
397 if (theme) {
398 self->theme = retain(theme);
399 } else {
400 self->theme = $(alloc(Theme), init);
401 }
402 }
403
405}
static void invalidateStyle(View *self)
Definition View.c:1092
The Theme type.
Definition Theme.h:54

◆ setViewController()

void setViewController ( WindowController *  self,
ViewController *  viewController 
)

Sets this WindowController's ViewController.

Parameters
selfThe WindowController.
viewControllerThe ViewController.

Definition at line 411 of file WindowController.c.

411 {
412
413 if (self->viewController != viewController || self->viewController == NULL) {
414
415 SDL_SetPointerProperty(SDL_GetWindowProperties(self->window), "keyResponder", NULL);
416
417 if (self->viewController) {
419 $(self->viewController->view, moveToWindow, NULL);
421 }
422
423 release(self->viewController);
424
425 if (viewController) {
426 self->viewController = retain(viewController);
427 } else {
428 self->viewController = $(alloc(ViewController), init);
429 }
430
432
434 $(self->viewController->view, moveToWindow, self->window);
436 }
437}
static void moveToWindow(View *self, SDL_Window *window)
Definition View.c:1351
static void viewWillAppear(ViewController *self)
static void viewWillDisappear(ViewController *self)
static void loadViewIfNeeded(ViewController *self)
static void viewDidAppear(ViewController *self)
static void viewDidDisappear(ViewController *self)

◆ setWindow()

void setWindow ( WindowController *  self,
SDL_Window *  window 
)

Sets this WindowController's window.

Parameters
selfThe WindowController.
windowThe window.

Definition at line 443 of file WindowController.c.

443 {
444
445 assert(window);
446
447 self->window = window;
448
449 SDL_PropertiesID properties = SDL_GetWindowProperties(self->window);
450
451 SDL_SetPointerProperty(properties, "windowController", self);
452 SDL_SetPointerProperty(properties, "keyResponder", NULL);
453 SDL_SetPointerProperty(properties, "touchResponder", NULL);
454
455 if (self->renderer) {
456 $(self->renderer->device, setWindow, self->window);
457 }
458
459 if (self->viewController) {
460 $(self->viewController->view, moveToWindow, self->window);
461 }
462
463 if (self->debugViewController) {
465 }
466}
ViewController viewController
The superclass.

◆ toggleDebugger()

void toggleDebugger ( WindowController *  self)

Toggles the debugger tools.

Parameters
selfThe WindowViewController.

Definition at line 472 of file WindowController.c.

472 {
473
474 if (self->debugViewController == NULL) {
475
477 assert(self->debugViewController);
478
480
485
486 if (self->viewController) {
487 $(self->viewController->view, addClassName, "debug");
488 }
489 } else {
490 self->debugViewController = release(self->debugViewController);
491
492 if (self->viewController) {
493 $(self->viewController->view, removeClassName, "debug");
494 }
495 }
496}
static void loadView(ViewController *self)
static void removeClassName(View *self, const char *className)
Definition View.c:1445
static void addClassName(View *self, const char *className)
Definition View.c:183
The DebugViewController type.

◆ touchResponder() [1/2]

View * touchResponder ( const WindowController *  self)
Parameters
selfThe WindowController.
Returns
The touch responder or NULL.
See also
View::hitTest(const View *, const SDL_Point *)

Definition at line 502 of file WindowController.c.

502 {
503 return SDL_GetPointerProperty(SDL_GetWindowProperties(self->window), "touchResponder", NULL);
504}

◆ touchResponder() [2/2]

View * touchResponder ( const WindowController *  self,
const SDL_Event *  event 
)

◆ windowController()

WindowController * windowController ( SDL_Window *  window)
Parameters
windowThe window.
Returns
The WindowController bound to the given window.

Definition at line 540 of file WindowController.c.

540 {
541
542 assert(window);
543
544 return SDL_GetPointerProperty(SDL_GetWindowProperties(window), "windowController", NULL);
545}

Field Documentation

◆ debugViewController

DebugViewController* WindowController::debugViewController

The DebugViewController.

Definition at line 61 of file WindowController.h.

◆ interface

WindowControllerInterface* WindowController::interface[0]
protected

The interface type.

Definition at line 56 of file WindowController.h.

◆ object

Object WindowController::object

The superclass.

Definition at line 50 of file WindowController.h.

◆ renderer

Renderer* WindowController::renderer

The Renderer.

Definition at line 66 of file WindowController.h.

◆ theme

Theme* WindowController::theme

The Theme.

Definition at line 71 of file WindowController.h.

◆ viewController

ViewController* WindowController::viewController

The ViewController.

Definition at line 76 of file WindowController.h.

◆ window

SDL_Window* WindowController::window

The window.

Definition at line 81 of file WindowController.h.


The documentation for this struct was generated from the following files: