ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
ScrollBar.c File Reference
#include <assert.h>
#include "ScrollBar.h"
#include "ScrollView.h"

Go to the source code of this file.

Macros

#define _Class   _ScrollBar
 

Functions

Class * _ScrollBar (void)
 
static void dealloc (Object *self)
 
static void didDragHandle (ScrollHandle *handle, float delta)
 ScrollHandleDelegate; maps handle travel onto the ScrollView's content offset.
 
static Viewinit (View *self)
 
static void initialize (Class *clazz)
 
static ScrollBarinitWithScrollView (ScrollBar *self, ScrollView *scrollView)
 
static void layoutSubviews (View *self)
 
static void respondToEvent (View *self, const SDL_Event *event)
 
static void setScrollView (ScrollBar *self, ScrollView *scrollView)
 

Variables

const EnumName ScrollBarVisibilityNames []
 

Macro Definition Documentation

◆ _Class

#define _Class   _ScrollBar

Definition at line 29 of file ScrollBar.c.

Function Documentation

◆ _ScrollBar()

Class * _ScrollBar ( void  )

Definition at line 225 of file ScrollBar.c.

225 {
226 static Class *clazz;
227 static Once once;
228
229 do_once(&once, {
230 clazz = _initialize(&(const ClassDef) {
231 .name = "ScrollBar",
232 .superclass = _View(),
233 .instanceSize = sizeof(ScrollBar),
234 .interfaceOffset = offsetof(ScrollBar, interface),
235 .interfaceSize = sizeof(ScrollBarInterface),
237 });
238 });
239
240 return clazz;
241}
static void initialize(Class *clazz)
Definition ScrollBar.c:209
Class * _View(void)
Definition View.c:2056
A draggable scrollbar, owned by a ScrollView.
Definition ScrollBar.h:85

◆ dealloc()

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

Definition at line 71 of file ScrollBar.c.

71 {
72
73 ScrollBar *this = (ScrollBar *) self;
74
75 release(this->handle);
76
77 super(Object, self, dealloc);
78}
static void dealloc(Object *self)
Definition ScrollBar.c:71

◆ didDragHandle()

static void didDragHandle ( ScrollHandle handle,
float  delta 
)
static

ScrollHandleDelegate; maps handle travel onto the ScrollView's content offset.

Definition at line 42 of file ScrollBar.c.

42 {
43
44 ScrollBar *self = handle->delegate.self;
45
46 if (self->scrollView) {
47
48 const SDL_Rect track = $((View *) self, bounds);
49 const SDL_Size content = $((View *) self->scrollView->contentView, size);
50 const SDL_Rect visible = $((View *) self->scrollView, bounds);
51
52 const int scrollRange = content.h - visible.h;
53 const int travel = track.h - ((View *) self->handle)->frame.h;
54
55 if (scrollRange > 0 && travel > 0) {
56
57 SDL_Point offset = self->scrollView->contentOffset;
58 offset.y -= (int) (delta * ((float) scrollRange / travel));
59
60 $(self->scrollView, scrollToOffset, &offset);
61 ((View *) self)->needsLayout = true;
62 }
63 }
64}
static SDL_Size size(const Image *self)
Definition Image.c:181
static SDL_Rect bounds(const View *self)
Definition View.c:492
ScrollView * scrollView
The ScrollView this bar drives. Weak reference (not retained).
Definition ScrollBar.h:102
ScrollHandle * handle
The grabby-widget: the draggable handle (.handle). Its own min-height (a standard View attribute) flo...
Definition ScrollBar.h:108
ident self
The delegate self pointer (the ScrollBar).
ScrollHandleDelegate delegate
The delegate.
View * contentView
The content View.
Definition ScrollView.h:82
SDL_Point contentOffset
The content View offset.
Definition ScrollView.h:77
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition View.h:134

◆ init()

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

Definition at line 85 of file ScrollBar.c.

85 {
86 return (View *) $((ScrollBar *) self, initWithScrollView, NULL);
87}
static ScrollBar * initWithScrollView(ScrollBar *self, ScrollView *scrollView)
Definition ScrollBar.c:173

◆ initialize()

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

Definition at line 209 of file ScrollBar.c.

209 {
210
211 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
212
213 ((ViewInterface *) clazz->interface)->init = init;
214 ((ViewInterface *) clazz->interface)->layoutSubviews = layoutSubviews;
215 ((ViewInterface *) clazz->interface)->respondToEvent = respondToEvent;
216
217 ((ScrollBarInterface *) clazz->interface)->initWithScrollView = initWithScrollView;
218 ((ScrollBarInterface *) clazz->interface)->setScrollView = setScrollView;
219}
static void setScrollView(ScrollBar *self, ScrollView *scrollView)
Definition ScrollBar.c:197
static View * init(View *self)
Definition ScrollBar.c:85
static void respondToEvent(View *self, const SDL_Event *event)
Definition ScrollBar.c:127
static void layoutSubviews(View *self)
Definition ScrollBar.c:92
void setScrollView(ScrollBar *self, ScrollView *scrollView)
Binds this ScrollBar to the given ScrollView and syncs the handle.
Definition ScrollBar.c:197
layoutSubviews(View *self)
Performs layout for this View's immediate subviews.
Definition Box.c:74

◆ initWithScrollView()

static ScrollBar * initWithScrollView ( ScrollBar self,
ScrollView scrollView 
)
static

Definition at line 173 of file ScrollBar.c.

173 {
174
175 self = (ScrollBar *) super(View, self, initWithFrame, NULL);
176 if (self) {
177
178 $((View *) self, addClassName, "scrollBar");
179 ((View *) self)->clipsSubviews = true;
180
181 self->handle = $(alloc(ScrollHandle), initWithFrame, NULL);
182 assert(self->handle);
183 self->handle->delegate.self = self;
185 $((View *) self, addSubview, (View *) self->handle);
186
187 $(self, setScrollView, scrollView);
188 }
189
190 return self;
191}
static Box * initWithFrame(Box *self, const SDL_Rect *frame)
Definition Box.c:92
static void addSubview(View *self, View *subview)
Definition PageView.c:49
static void didDragHandle(ScrollHandle *handle, float delta)
ScrollHandleDelegate; maps handle travel onto the ScrollView's content offset.
Definition ScrollBar.c:42
static void addClassName(View *self, const char *className)
Definition View.c:159
void(* didDrag)(ScrollHandle *handle, float delta)
Called for each mouse-motion increment while the handle is grabbed.
A draggable scrollbar handle.

◆ layoutSubviews()

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

Definition at line 92 of file ScrollBar.c.

92 {
93
94 ScrollBar *this = (ScrollBar *) self;
95
96 super(View, self, layoutSubviews);
97
98 if (this->scrollView == NULL || this->scrollView->contentView == NULL) {
99 return;
100 }
101
102 const SDL_Rect track = $(self, bounds);
103 const SDL_Size content = $(this->scrollView->contentView, size);
104 const SDL_Rect visible = $((View *) this->scrollView, bounds);
105
106 View *handle = (View *) this->handle;
107
108 if (content.h <= visible.h || track.h <= 0) {
109 handle->frame = (SDL_Rect) { 0, 0, track.w, track.h };
110 } else {
111
112 const int scrollRange = content.h - visible.h;
113
114 int handleH = (int) ((float) track.h * visible.h / content.h);
115 handleH = clamp(handleH, handle->minSize.h, track.h);
116
117 const int travel = track.h - handleH;
118 const float fraction = clamp((float) (-this->scrollView->contentOffset.y) / scrollRange, 0.f, 1.f);
119
120 handle->frame = (SDL_Rect) { 0, (int) (fraction * travel), track.w, handleH };
121 }
122}
SDL_Size minSize
The minimum size this View may be resized to during layout.
Definition View.h:212
SDL_Rect frame
The frame, relative to the superview.
Definition View.h:191

◆ respondToEvent()

static void respondToEvent ( View self,
const SDL_Event *  event 
)
static
See also
View::respondToEvent(View *, const SDL_Event *)

Definition at line 127 of file ScrollBar.c.

127 {
128
129 ScrollBar *this = (ScrollBar *) self;
130
131 switch (event->type) {
132
133 case SDL_EVENT_MOUSE_BUTTON_DOWN:
134 if (this->scrollView) {
135
136 const SDL_Point point = MakePoint(event->button.x, event->button.y);
137 const SDL_Rect handleFrame = $((View *) this->handle, renderFrame);
138 const SDL_Rect visible = $((View *) this->scrollView, bounds);
139
140 SDL_Point offset = this->scrollView->contentOffset;
141
142 if (point.y < handleFrame.y) {
143 offset.y += visible.h;
144 } else if (point.y > handleFrame.y + handleFrame.h) {
145 offset.y -= visible.h;
146 }
147
148 $(this->scrollView, scrollToOffset, &offset);
149 self->needsLayout = true;
150 }
151 return;
152
153 case SDL_EVENT_MOUSE_BUTTON_UP:
154 $(self, resignTouchResponder);
155 return;
156
157 case SDL_EVENT_MOUSE_MOTION:
158 return;
159
160 default:
161 break;
162 }
163
164 super(View, self, respondToEvent, event);
165}
static void resignTouchResponder(View *self)
Definition View.c:1500
static SDL_Rect renderFrame(const View *self)
Definition View.c:1444
bool needsLayout
If true, this View will layout its subviews before it is drawn.
Definition View.h:222

◆ setScrollView()

static void setScrollView ( ScrollBar self,
ScrollView scrollView 
)
static

Definition at line 197 of file ScrollBar.c.

197 {
198
199 self->scrollView = scrollView;
200
201 ((View *) self)->needsLayout = true;
202}

Variable Documentation

◆ ScrollBarVisibilityNames

const EnumName ScrollBarVisibilityNames[]
Initial value:
= MakeEnumNames(
MakeEnumAlias(ScrollBarShow, show),
MakeEnumAlias(ScrollBarHide, hide),
MakeEnumAlias(ScrollBarAuto, auto)
)
@ ScrollBarHide
Definition ScrollBar.h:68
@ ScrollBarAuto
Definition ScrollBar.h:70
@ ScrollBarShow
Definition ScrollBar.h:69

Definition at line 31 of file ScrollBar.c.