1 /*---------------------------------------------------------------------------*
2 
3   Copyright (C) Nintendo.  All rights reserved.
4 
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law.  They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10 
11  *---------------------------------------------------------------------------*/
12 
13     // Adds the tab to the list of tabs
Add(Window * window,MenuItem * object,bool active)14 void TabObject::Add(Window* window, MenuItem* object, bool active)
15 {
16     if (this->next != this)
17         Remove();
18 
19     TabObject* end = window->dummyTab.prev;
20 
21     end->next = this;
22     this->prev = end;
23 
24     this->next = &window->dummyTab;
25     window->dummyTab.prev = this;
26 
27     this->object = object;
28     this->active = active;
29     this->window = window;
30 }
31 
32     // Removes the tab from the list of tabs
Remove()33 void TabObject::Remove()
34 {
35         // Oddly enough, one that isn't attached will end up doing nothing here
36     this->next->prev = this->prev;
37     this->prev->next = this->next;
38 
39     this->next = this;
40     this->prev = this;
41 
42     this->active = false;
43 }
44 
45     // Updates the cursor's position based on tabbing, if need be
UpdateTabbing()46 void WindowManager::UpdateTabbing()
47 {
48     if (!tabIndex || tabSubIndex != -1)
49         return;
50 
51     peripheral->CursorX() = tabIndex->object->x + tabIndex->window->GetX();
52     peripheral->CursorY() = tabIndex->object->y + tabIndex->window->GetY();
53 
54         // Make sure the tab is visible in the window!
55     if (peripheral->CursorY() > tabIndex->window->GetTop())
56     {
57         tabIndex->window->GetOffY() -= peripheral->CursorY() - tabIndex->window->GetTop();
58 
59         if (tabIndex->window->GetOffY() < 0)
60             tabIndex->window->GetOffY() = 0;
61 
62         tabIndex->window->GetMaster()->scrollBar->pos = tabIndex->window->GetOffY();
63 
64         peripheral->CursorY() = tabIndex->object->y + tabIndex->window->GetY();
65     }
66 
67     if (peripheral->CursorY() < tabIndex->window->GetBottom())
68     {
69         tabIndex->window->GetOffY() += tabIndex->window->GetBottom() - peripheral->CursorY();
70 
71         if (tabIndex->window->GetOffY() < 0)
72             tabIndex->window->GetOffY() = 0;
73 
74         tabIndex->window->GetMaster()->scrollBar->pos = tabIndex->window->GetOffY();
75 
76         peripheral->CursorY() = tabIndex->object->y + tabIndex->window->GetY();
77     }
78 }
79 
80     // Forces the tab to be on something valid, if tab was pressed
ForceValidTabForward()81 void WindowManager::ForceValidTabForward()
82 {
83     //OSReport("\nStart:  0x%x\n", tabIndex);
84     if (!tabIndex)
85         return;
86 
87     Window* startWin = tabIndex->window;
88     Window* window = startWin;
89 
90     TabObject* start = tabIndex;
91 
92     while (true)
93     {
94             // Loop through each tab this window has
95         //OSReport("window = 0x%x(%s)\n", window, window->GetName());
96         while (window->Active() && tabIndex != &window->dummyTab)
97         {
98             //OSReport("0x%x\n", tabIndex);
99             if (tabIndex->active && tabIndex->object->Active())
100                 return;
101 
102             tabIndex = tabIndex->next;
103 
104             if (start == tabIndex)
105             {
106                 //OSReport("No tab found!\n");
107                 tabIndex = NULL;
108                 tabSubIndex = -1;
109                 return;
110             }
111         }
112         //OSReport("-0x%x\n", tabIndex);
113 
114             // If the window has a child, loop through the child window next!
115         if (window->child)
116         {
117             //OSReport("To child!  ");
118             window = window->child;
119 
120             tabIndex = window->dummyTab.next;
121 
122             if (start == tabIndex)
123                 break;
124 
125             continue;
126         }
127 
128             // If we were in a child window, go back to the original master before going to the next window
129         while (window->master)
130         {
131             window = window->master;
132             //OSReport("master = 0x%x\n", window);
133         }
134 
135             // Find the next non-child window!
136         do
137         {
138             if (window->number + 1 < windowList.size())
139                 window = windowList[window->number + 1];
140             else
141                 window = windowList[0];
142 
143             //OSReport("next = 0x%x\n", window);
144         }
145         while (window->master);
146 
147         tabIndex = window->dummyTab.next;
148 
149         if (start == tabIndex)
150             break;
151     }
152 
153     //OSReport("No tab found!\n");
154 
155     tabIndex = NULL;
156     tabSubIndex = -1;
157 }
158 
159     // Forces the tab to be on something valid, if tab was pressed
ForceValidTabBack()160 void WindowManager::ForceValidTabBack()
161 {
162     if (!tabIndex)
163         return;
164 
165     Window* startWin = tabIndex->window;
166     Window* window = startWin;
167 
168     TabObject* start = tabIndex;
169 
170     while (true)
171     {
172             // Loop through each tab this window has
173         while (window->Active() && tabIndex != &window->dummyTab)
174         {
175             if (tabIndex->active && tabIndex->object->Active())
176                 return;
177 
178             tabIndex = tabIndex->prev;
179 
180             if (start == tabIndex)
181             {
182                 tabIndex = NULL;
183                 tabSubIndex = -1;
184                 return;
185             }
186         }
187 
188             // If we were in a child window, go to the master next!
189         if (window->master)
190         {
191             window = window->master;
192 
193             tabIndex = window->dummyTab.prev;
194 
195             if (start == tabIndex)
196                 break;
197 
198             continue;
199         }
200 
201             // Find the previous non-child window!
202         do
203         {
204             if (window->number > 0)
205                 window = windowList[window->number - 1];
206             else
207                 window = windowList[windowList.size() - 1];
208         }
209         while (window->master);
210 
211             // Go to the furthest child of this window first
212         while (window->child)
213             window = window->child;
214 
215         tabIndex = window->dummyTab.prev;
216 
217         if (start == tabIndex)
218             break;
219     }
220 
221     tabIndex = NULL;
222     tabSubIndex = -1;
223 }
224