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 View * init (View *self)
 
static void initialize (Class *clazz)
 
static ScrollBar * initWithScrollView (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 224 of file ScrollBar.c.

224 {
225 static Class *clazz;
226 static Once once;
227
228 do_once(&once, {
229 clazz = _initialize(&(const ClassDef) {
230 .name = "ScrollBar",
231 .superclass = _View(),
232 .instanceSize = sizeof(ScrollBar),
233 .interfaceSize = sizeof(ScrollBarInterface),
234 .initialize = initialize,
235 });
236 });
237
238 return clazz;
239}
static void initialize(Class *clazz)
Definition ScrollBar.c:208
Class * _View(void)
Definition View.c:2336
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, setNeedsLayout);
62 }
63 }
64}
static SDL_Size size(const Image *self)
Definition Image.c:416
static void setNeedsLayout(View *self)
Definition View.c:1865
static SDL_Rect bounds(const View *self)
Definition View.c:552
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:84
SDL_Point contentOffset
The content View offset.
Definition ScrollView.h:77
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition View.h:225

◆ 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 208 of file ScrollBar.c.

208 {
209
210 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
211
212 ((ViewInterface *) clazz->interface)->init = init;
213 ((ViewInterface *) clazz->interface)->layoutSubviews = layoutSubviews;
214 ((ViewInterface *) clazz->interface)->respondToEvent = respondToEvent;
215
216 ((ScrollBarInterface *) clazz->interface)->initWithScrollView = initWithScrollView;
217 ((ScrollBarInterface *) clazz->interface)->setScrollView = setScrollView;
218}
static void setScrollView(ScrollBar *self, ScrollView *scrollView)
Definition ScrollBar.c:196
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:196
layoutSubviews(View *self)
Arranges this View's immediate subviews within its (already final) frame.
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
180 self->handle = $(alloc(ScrollHandle), initWithFrame, NULL);
181 assert(self->handle);
182 self->handle->delegate.self = self;
184 $((View *) self, addSubview, (View *) self->handle);
185
186 $(self, setScrollView, scrollView);
187 }
188
189 return self;
190}
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:183
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:345
SDL_Rect frame
The frame, relative to the superview.
Definition View.h:301

◆ 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, setNeedsLayout);
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:1692
static SDL_Rect renderFrame(const View *self)
Definition View.c:1629

◆ setScrollView()

static void setScrollView ( ScrollBar *  self,
ScrollView *  scrollView 
)
static

Definition at line 196 of file ScrollBar.c.

196 {
197
198 self->scrollView = scrollView;
199
200 $((View *) self, setNeedsLayout);
201}

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.