9 # error This is a userspace-only header, not allowed by the current build.
12 #include <sifteo/menu/types.h>
21 inline Menu::Menu(
VideoBuffer &vid,
const MenuAssets *aAssets, MenuItem *aItems)
23 init(vid, aAssets, aItems);
26 inline void Menu::init(
VideoBuffer &vid,
const MenuAssets *aAssets, MenuItem *aItems)
29 hasBeenStarted =
false;
31 currentEvent.type = MENU_UNEVENTFUL;
34 changeState(MENU_STATE_START);
43 while (items[i].icon !=
NULL) {
44 if (kIconTileWidth == 0) {
45 kIconTileWidth = items[i].icon->tileWidth();
46 kIconTileHeight = items[i].icon->tileHeight();
47 kEndCapPadding = (kNumVisibleTilesX - kIconTileWidth) * (TILE / 2.f);
48 ASSERT((kItemPixelWidth() - kIconPixelWidth()) % TILE == 0);
50 ASSERT(items[i].icon->tileWidth() == kIconTileWidth);
51 ASSERT(items[i].icon->tileHeight() == kIconTileHeight);
55 if (items[i].label !=
NULL) {
56 ASSERT(items[i].label->tileWidth() == kNumVisibleTilesX);
57 if (kHeaderHeight == 0) {
58 kHeaderHeight = items[i].label->tileHeight();
60 ASSERT(items[i].label->tileHeight() == kHeaderHeight);
76 while (assets->tips[i] !=
NULL) {
77 ASSERT(assets->tips[i]->tileWidth() == kNumVisibleTilesX);
78 if (kFooterHeight == 0) {
79 kFooterHeight = assets->tips[i]->tileHeight();
81 ASSERT(assets->tips[i]->tileHeight() == kFooterHeight);
88 ASSERT(assets->background);
89 ASSERT(assets->background->tileWidth() == 1 && assets->background->tileHeight() == 1);
91 ASSERT(assets->footer->tileWidth() == kNumVisibleTilesX);
92 if (kFooterHeight == 0) {
93 kFooterHeight = assets->footer->tileHeight();
95 ASSERT(assets->footer->tileHeight() == kFooterHeight);
100 ASSERT(assets->header->tileWidth() == kNumVisibleTilesX);
101 if (kHeaderHeight == 0) {
102 kHeaderHeight = assets->header->tileHeight();
104 ASSERT(assets->header->tileHeight() == kHeaderHeight);
113 setIconYOffset(kDefaultIconYOffset);
114 setPeekTiles(kDefaultPeekTiles);
122 inline CubeID Menu::cube()
const
124 return vid ? vid->
cube() : CubeID();
127 inline bool Menu::pollEvent(
struct MenuEvent *ev)
130 ASSERT(currentEvent.type != MENU_PREPAINT);
137 if (dispatchEvent(ev)) {
138 return (ev->type != MENU_EXIT);
145 if (currentState != MENU_STATE_START) {
148 if (dispatchEvent(ev)) {
149 return (ev->type != MENU_EXIT);
153 const float kAccelScalingFactor = -0.25f;
154 accel = kAccelScalingFactor * vid->virtualAccel().xy();
157 switch (currentState) {
158 case MENU_STATE_START:
161 case MENU_STATE_STATIC:
164 case MENU_STATE_TILTING:
167 case MENU_STATE_INERTIA:
170 case MENU_STATE_FINISH:
173 case MENU_STATE_HOP_UP:
176 case MENU_STATE_PAN_TARGET:
177 transFromPanTarget();
180 if (dispatchEvent(ev)) {
181 return (ev->type != MENU_EXIT);
185 switch (currentState) {
186 case MENU_STATE_START:
189 case MENU_STATE_STATIC:
192 case MENU_STATE_TILTING:
195 case MENU_STATE_INERTIA:
198 case MENU_STATE_FINISH:
201 case MENU_STATE_HOP_UP:
204 case MENU_STATE_PAN_TARGET:
208 if (dispatchEvent(ev)) {
209 return (ev->type != MENU_EXIT);
214 currentEvent.type = MENU_PREPAINT;
219 inline void Menu::reset()
221 changeState(MENU_STATE_START);
224 inline void Menu::replaceIcon(uint8_t item,
const AssetImage *icon,
const AssetImage *label)
228 items[item].icon = icon;
229 for (
int i = prev_ut; i < prev_ut + kNumTilesX; i++)
230 if (itemVisibleAtCol(item, i))
234 uint8_t currentItem = computeSelected();
235 items[item].label = label;
237 if (kHeaderHeight && currentState == MENU_STATE_STATIC &&
240 const AssetImage& label = items[currentItem].label
241 ? *items[currentItem].label
243 vid->bg1.image(
vec(0,0), label);
248 inline bool Menu::itemVisible(uint8_t item)
250 ASSERT(item >= 0 && item < numItems);
252 for (
int i =
MAX(0, prev_ut); i < prev_ut + kNumTilesX; i++) {
253 if (itemVisibleAtCol(item, i))
return true;
258 inline void Menu::setIconYOffset(uint8_t px)
260 ASSERT(px >= 0 || px < kNumTilesX * 8);
266 inline void Menu::setPeekTiles(uint8_t numTiles)
268 ASSERT(numTiles >= 1 || numTiles * 2 < kNumTilesX);
269 kPeekTiles = numTiles;
282 inline void Menu::anchor(uint8_t item,
bool hopUp, int8_t panTarget)
286 targetItem = panTarget;
289 position = stoppingPositionFor(startingItem);
290 prev_ut = computeCurrentTile() + kNumTilesX;
293 changeState(MENU_STATE_HOP_UP);
302 inline bool Menu::isTilted()
304 const float robustThreshold = kAccelThresholdOn * 1.3;
305 return (
abs(accel.x) >= robustThreshold);
308 inline bool Menu::isHorizontal()
310 const float robustThreshold = kAccelThresholdOn * 0.3;
311 return (
abs(accel.x) < robustThreshold);
314 inline bool Menu::isAtEdge()
316 uint8_t item = computeSelected();
317 return (item == 0 || item == numItems - 1);
320 inline bool Menu::isTiltingAtEdge()
326 uint8_t item = computeSelected();
327 int8_t direction = accel.x > 0 ? 1 : -1;
329 return ((direction < 0 && item == 0) ||
330 (direction > 0 && item == numItems - 1));
333 inline void Menu::setNumTips(uint8_t nt)
340 inline int Menu::getCurrentTip()
342 ASSERT(currentTip < numTips);