Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
MenuView.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: MenuView.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12 
13 */
14 
15 #include "MemDebug.h"
16 #include "MenuView.h"
17 
18 #include "Color.h"
19 #include "Window.h"
20 #include "Video.h"
21 #include "DataLoader.h"
22 #include "Scene.h"
23 #include "FontMgr.h"
24 #include "Keyboard.h"
25 #include "Mouse.h"
26 #include "MouseController.h"
27 #include "Menu.h"
28 #include "Button.h"
29 #include "Game.h"
30 #include "FormatUtil.h"
31 
32 // +--------------------------------------------------------------------+
33 
35 : View(c),
36 mouse_down(0), right_down(0), shift_down(0), show_menu(false),
37 action(0), menu(0), menu_item(0), selected(0),
38 text_color(Color::White), back_color(Color::Black)
39 {
40  right_start.x = 0;
41  right_start.y = 0;
42 
43  OnWindowMove();
44 }
45 
47 {
48 }
49 
50 // +--------------------------------------------------------------------+
51 
52 void
54 {
55  offset.x = window->X();
56  offset.y = window->Y();
57  width = window->Width();
58  height = window->Height();
59 }
60 
61 // +--------------------------------------------------------------------+
62 
63 void
65 {
66  if (show_menu)
67  DrawMenu();
68 }
69 
70 // +--------------------------------------------------------------------+
71 
72 void
74 {
75  static DWORD rbutton_latch = 0;
76 
77  action = 0;
78 
79  if (Mouse::RButton()) {
81  if (!right_down && (!mouse_con || !mouse_con->Active())) {
82  rbutton_latch = Game::RealTime();
83  right_down = true;
84  show_menu = false;
85  }
86  }
87  else {
88  if (right_down && (Game::RealTime() - rbutton_latch < 250)) {
89  right_start.x = Mouse::X() - offset.x;
90  right_start.y = Mouse::Y() - offset.y;
91  show_menu = true;
93  }
94 
95  right_down = false;
96  }
97 
99 
100  if (!mouse_con || !mouse_con->Active()) {
101  if (Mouse::LButton()) {
102  if (!mouse_down)
103  shift_down = Keyboard::KeyDown(VK_SHIFT);
104 
105  mouse_down = true;
106  }
107 
108  else if (mouse_down) {
109  int mouse_x = Mouse::X() - offset.x;
110  int mouse_y = Mouse::Y() - offset.y;
111  int keep_menu = false;
112 
113  if (show_menu) {
114  keep_menu = ProcessMenuItem();
115  Mouse::Show(true);
116  }
117 
118  mouse_down = false;
119 
120  if (!keep_menu) {
122  show_menu = false;
123  }
124  }
125  }
126 }
127 
128 // +--------------------------------------------------------------------+
129 
130 int
132 {
133  if (!menu_item || !menu_item->GetEnabled())
134  return false;
135 
136  if (menu_item->GetSubmenu()) {
138  while (++item)
139  if (item.value() == menu_item)
140  item->SetSelected(2);
141  else
142  item->SetSelected(0);
143 
145  return true; // keep menu showing
146  }
147 
148  action = menu_item->GetData();
150  return false;
151 }
152 
153 // +--------------------------------------------------------------------+
154 
155 void
157 {
158  menu_item = 0;
159 
160  if (menu) {
161  int mx = right_start.x - 2;
162  int my = right_start.y - 2;
163 
164  DrawMenu(mx, my, menu);
165  }
166 }
167 
168 void
169 MenuView::DrawMenu(int mx, int my, Menu* m)
170 {
171  if (m) {
172  MenuItem* locked_item = 0;
173  Menu* submenu = 0;
174  int subx = 0;
175  int suby = 0;
176  Font* font = FontMgr::Find("HUD");
177 
178  Rect menu_rect(mx, my, 100, m->NumItems() * 10 + 6);
179 
180  int max_width = 0;
181  int max_height = 0;
182  int extra_width = 16;
183 
184  ListIter<MenuItem> item = m->GetItems();
185  while (++item) {
186  menu_rect.w = width/2;
187 
188  if (item->GetText().length()) {
189  window->SetFont(font);
190  window->DrawText(item->GetText(), 0, menu_rect, DT_LEFT|DT_SINGLELINE|DT_CALCRECT);
191  if (menu_rect.w > max_width)
192  max_width = menu_rect.w;
193  max_height += 11;
194 
195  if (item->GetSubmenu())
196  extra_width = 28;
197 
198  if (item->GetSelected() > 1)
199  locked_item = item.value();
200  }
201  else {
202  max_height += 4;
203  }
204  }
205 
206  menu_rect.h = max_height + 6;
207  menu_rect.w = max_width + extra_width;
208 
209  if (menu_rect.x + menu_rect.w >= width)
210  menu_rect.x = width - menu_rect.w - 2;
211 
212  if (menu_rect.y + menu_rect.h >= height)
213  menu_rect.y = height - menu_rect.h - 2;
214 
215  window->FillRect(menu_rect, back_color * 0.2);
216  window->DrawRect(menu_rect, back_color);
217 
218  Rect item_rect = menu_rect;
219 
220  item_rect.x += 4;
221  item_rect.y += 3;
222  item_rect.w -= 8;
223  item_rect.h = 12;
224 
225  item.reset();
226  while (++item) {
227  int line_height = 0;
228 
229  if (item->GetText().length()) {
230  Rect fill_rect = item_rect;
231  fill_rect.Inflate(2,-1);
232  fill_rect.y -= 1;
233 
234  int mx = Mouse::X() - offset.x;
235  int my = Mouse::Y() - offset.y;
236 
237  // is this item picked?
238  if (menu_rect.Contains(mx, my)) {
239  if (my >= fill_rect.y && my <= fill_rect.y+fill_rect.h) {
240  if (Mouse::LButton()) {
241  menu_item = item.value();
242  item->SetSelected(2);
243  if (locked_item && locked_item->GetMenu() == m)
244  locked_item->SetSelected(0);
245  locked_item = menu_item;
246  }
247  else if (!locked_item || locked_item->GetMenu() != m) {
248  item->SetSelected(true);
249  menu_item = item.value();
250  }
251 
252  if (menu_item && menu_item != selected) {
255  }
256  }
257  else if (item.value() != locked_item) {
258  item->SetSelected(false);
259  }
260  }
261 
262  if (item->GetSelected()) {
263  window->FillRect(fill_rect, back_color * 0.35);
264  window->DrawRect(fill_rect, back_color * 0.75);
265 
266  if (item->GetSubmenu()) {
267  submenu = item->GetSubmenu();
268  subx = menu_rect.x + max_width + extra_width;
269  suby = fill_rect.y - 3;
270  }
271  }
272 
273  if (item->GetEnabled())
274  font->SetColor(text_color);
275  else
276  font->SetColor(text_color * 0.33);
277 
278  window->SetFont(font);
279  window->DrawText(item->GetText(), 0, item_rect, DT_LEFT|DT_SINGLELINE);
280  line_height = 11;
281  }
282  else {
283  window->DrawLine(item_rect.x,
284  item_rect.y + 2,
285  item_rect.x + max_width + extra_width - 8,
286  item_rect.y + 2,
287  back_color);
288  line_height = 4;
289  }
290 
291  if (item->GetSubmenu()) {
292  int left = item_rect.x + max_width + 10;
293  int top = item_rect.y + 1;
294 
295  // draw the arrow:
296  POINT arrow[3];
297 
298  arrow[0].x = left;
299  arrow[0].y = top;
300  arrow[1].x = left + 8;
301  arrow[1].y = top + 4;
302  arrow[2].x = left;
303  arrow[2].y = top + 8;
304 
305  window->FillPoly(3, arrow, back_color);
306  }
307 
308  item_rect.y += line_height;
309  }
310 
311  if (submenu) {
312  if (subx + 60 > width)
313  subx = menu_rect.x - 60;
314 
315  DrawMenu(subx, suby, submenu);
316  }
317  }
318 }
319 
320 // +--------------------------------------------------------------------+
321 
322 void
324 {
325  if (menu) {
326  ListIter<MenuItem> item = menu->GetItems();
327  while (++item) {
328  item->SetSelected(0);
329  if (item->GetSubmenu())
331  }
332  }
333 }