Chesto 0.9
A declarative and element-based library for creating GUIs on homebrew'd consoles
ListElement.cpp
1#include "ListElement.hpp"
2
3namespace Chesto {
4
6{
7 bool ret = false;
8
9 // if we're hidden, don't process input
10 if (hidden) return ret;
11
12 // perform inertia scrolling for this element
13 ret |= this->handleInertiaScroll(event);
14
15 ret |= super::process(event);
16
17 return ret;
18}
19
20bool ListElement::processUpDown(InputEvents* event)
21{
22 bool ret = false;
23 int SPEED = 1;
24
25 // handle up and down for the scroll view
26 if (event->isKeyDown())
27 {
28 // scroll the view by offsetting the elastic counter
29 event->wheelScroll += (SPEED * event->held(UP_BUTTON) - SPEED * event->held(DOWN_BUTTON));
30
31 ret |= event->held(UP_BUTTON) || event->held(DOWN_BUTTON);
32 }
33
34 return ret;
35}
36
37bool ListElement::handleInertiaScroll(InputEvents* event)
38{
39 bool ret = false;
40 ListElement* elem = this;
41
42 if (event->isTouchDown())
43 {
44 // make sure that the mouse down's X coordinate is over the app list (not sidebar)
45 if (event->xPos < elem->xAbs)
46 return false;
47
48 // saw mouse down so set it in our element object
49 elem->dragging = true;
50 elem->lastMouseY = event->yPos;
51 elem->initialTouchDown = event->yPos;
52
53 ret |= true;
54 }
55 // drag event for scrolling up or down
56 else if (event->isTouchDrag())
57 {
58 if (elem->dragging)
59 {
60 // prevent scrolling until we exceed a treshold distance in the Y direction
61 if (this->initialTouchDown >= 0 && (abs(event->yPos - this->initialTouchDown) < 10 * getEffectiveScale()))
62 return false;
63
64 this->initialTouchDown = -1;
65
66 int distance = event->yPos - elem->lastMouseY;
67 elem->y += distance;
68 elem->lastMouseY = event->yPos;
69
70 // use the last distance as the rubber band value
71 elem->elasticCounter = distance;
72
73 ret |= true;
74 }
75 }
76 else if (event->isTouchUp())
77 {
78 // mouse up, no more mouse down (TODO: fire selected event here)
79 elem->dragging = false;
80
81 // if the scroll offset is less than the total number of apps
82 // (put on the mouse up to make it "snap" when going out of bounds)
83 // TODO: account for max number of apps too (prevent scrolling down forever)
84 if (elem->y > minYScroll)
85 elem->y = minYScroll;
86
87 ret |= true;
88 }
89
90 // if mouse is up, and there's some elastic counter left, burn out remaining elastic value
91 if (!elem->dragging && elem->elasticCounter != 0)
92 {
93 elem->y += elem->elasticCounter;
94
95 // reduce the elastic counter by 5% each time (slows down the scroll)
96 elem->elasticCounter *= 0.95;
97
98 // if we're less than 10 pixels on the counter, just stop
99 if (abs(elem->elasticCounter) < 10)
100 elem->elasticCounter = 0;
101
102 // TODO: same problem as above todo, also extract into method?
103 if (elem->y > minYScroll)
104 elem->y = minYScroll;
105
106 ret |= true;
107 }
108
109 if (ret) event->isScrolling = true;
110
111 if (event->wheelScroll != 0)
112 {
113 // apply wheel scroll directly to y position, and then reset
114 elem->y += event->wheelScroll * 10;
115 if (elem->y > minYScroll)
116 elem->y = minYScroll;
117 event->wheelScroll *= 0.95;
118
119 if (abs(event->wheelScroll) < 0.1)
120 event->wheelScroll = 0;
121
122 ret |= true;
123 }
124
125 return ret;
126}
127
128} // namespace Chesto
bool hidden
whether this element should skip rendering or not
Definition: Element.hpp:119
virtual bool process(InputEvents *event)
process any input that is received for this element
Definition: Element.cpp:29
bool process(InputEvents *event)
process any input that is received for this element
Definition: ListElement.cpp:5