-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdrawer.c
executable file
·150 lines (126 loc) · 4.23 KB
/
drawer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* drawer.c */
#include <stdio.h>
#include "ui.h"
void DrawerCtor(struct Drawer *const self, Rectangle r)
{
ContainerCtor(&self->super, r);
self->aniState = STOP;
}
void DrawerStartDrag(struct Container *const self, Vector2 pos)
{
// fprintf(stdout, "DrawerStartDrag %.0f, %.0f\n", pos.x, pos.y);
struct Drawer *const dr = (struct Drawer*)self;
dr->dragStartPos = pos;
}
void DrawerDragBy(struct Container *const self, Vector2 delta)
{
// delta is the difference between the point now, and what it was previously
// (in gosol, delta is the difference between the point now and where the drag started)
struct Drawer *const dr = (struct Drawer*)self;
// dr->dragOffset.x = dr->dragOffset.x + delta.x;
// if ( dr->dragOffset.x > 0.0f ) {
// dr->dragOffset.x = 0.0f;
// }
dr->dragOffset.y = dr->dragOffset.y + delta.y;
if ( dr->dragOffset.y > 0.0f ) {
dr->dragOffset.y = 0.0f;
}
DrawerLayoutWidgets(self);
// fprintf(stdout, "DrawerDragBy %.0f,%.0f := %.0f,%.0f\n", delta.x, delta.y, dr->dragOffset.x, dr->dragOffset.y);
}
void DrawerStopDrag(struct Container *const self, Vector2 pos)
{
// fprintf(stdout, "DrawerStopDrag %.0f, %.0f\n", pos.x, pos.y);
(void)self;
(void)pos;
}
_Bool DrawerWasDragged(struct Container *const self, Vector2 pos)
{
struct Drawer *const dr = (struct Drawer*)self;
_Bool result = !(pos.x == dr->dragStartPos.x && pos.y == dr->dragStartPos.y);
// fprintf(stdout, "DrawerWasDragged %d\n", result);
return result;
}
void DrawerLayoutWidgets(struct Container *const self)
{
// arrange widgets vertically, stacked top to bottom
float x = WIDGET_PADDING;
float y = WIDGET_PADDING;
size_t index;
struct Drawer *dr = (struct Drawer*)self;
for ( struct Widget *w = ArrayFirst(dr->super.widgets, &index); w; w = ArrayNext(dr->super.widgets, &index) ) {
w->rect.x = x + dr->dragOffset.x;
w->rect.y = y + dr->dragOffset.y;
/*
make the drawer text widgets span the width of the drawer, rather than just
being confined to the text dimensions, otherwise drawer dragging requires
the touch be over the text, not just in the drawer
*/
w->rect.width = dr->super.rect.width - WIDGET_PADDING * 2.0f;
y += w->rect.height + WIDGET_PADDING;
}
}
void DrawerLayout(struct Container *const self, const int windowWidth, const int windowHeight)
{
(void)windowWidth;
struct Drawer *dr = (struct Drawer*)self;
dr->super.rect = (Rectangle){.x=-DRAWER_WIDTH, .y=TITLEBAR_HEIGHT, .width=DRAWER_WIDTH, .height=windowHeight - TITLEBAR_HEIGHT - STATUSBAR_HEIGHT};
DrawerLayoutWidgets(self);
}
void DrawerUpdate(struct Container *const self)
{
struct Drawer *dr = (struct Drawer*)self;
ContainerUpdate(self); // does nothing?
/* K&R style switch formatting, see P59 if you don't believe me */
switch (dr->aniState) {
case LEFT:
if ( dr->super.rect.x <= -DRAWER_WIDTH ) {
dr->super.rect.x = -(DRAWER_WIDTH);
dr->aniState = STOP;
} else {
dr->super.rect.x -= 16.0f;
}
break;
case STOP:
break;
case RIGHT:
if ( dr->super.rect.x >= 0.0f ) {
dr->super.rect.x = 0.0f;
dr->aniState = STOP;
} else {
dr->super.rect.x += 16.0f;
}
break;
default:
break;
}
}
void DrawerDraw(struct Container *const self)
{
ContainerDraw(self); // draws background then widgets
}
void DrawerFree(struct Container *const self)
{
// no extra variables added to Drawer (only functions), so use base class free
ContainerFree(self);
}
_Bool DrawerVisible(struct Drawer *const self)
{
// return self->super.rect.x > -1.0f; // don't compare a float with 0
return self->super.rect.x > -DRAWER_WIDTH / 2.0f;
}
void DrawerShow(struct Drawer *const self)
{
self->aniState = RIGHT;
// reset any drag offset so list starts un-vscrolled
self->dragOffset = (Vector2){.x=0.0f, .y=0.0f};
DrawerLayoutWidgets(&(self->super));
}
void DrawerHide(struct Drawer *const self)
{
if ( self->super.rect.x == -DRAWER_WIDTH ) {
self->aniState = STOP;
} else {
self->aniState = LEFT;
}
}