Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ScrollWindow.cpp
Go to the documentation of this file.
1 /* Project nGenEx
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: nGenEx.lib
6  FILE: ScrollWindow.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  ScrollWindow ActiveWindow class
13 */
14 
15 #include "MemDebug.h"
16 #include "ScrollWindow.h"
17 #include "Button.h"
18 #include "Bitmap.h"
19 #include "FormWindow.h"
20 #include "Video.h"
21 #include "Font.h"
22 #include "Keyboard.h"
23 #include "Mouse.h"
24 
25 
26 DWORD GetRealTime();
27 
28 // +--------------------------------------------------------------------+
29 
30 static int old_cursor;
31 
32 // +--------------------------------------------------------------------+
33 
34 ScrollWindow::ScrollWindow(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid, DWORD s, ActiveWindow* paw)
35 : ActiveWindow(p->GetScreen(), ax, ay, aw, ah, aid, s, paw)
36 {
37  captured = false;
38  dragging = false;
39  selecting = false;
41 
42  leading = 0;
44  dragdrop = false;
45  scroll_count = 0;
46  line_count = 0;
47  page_count = 0;
48  page_size = 1;
49  top_index = 0;
50  line_height = 0;
51  mouse_x = 0;
52  mouse_y = 0;
53 
54  smooth_scroll = false;
55  smooth_offset = 0;
56 
59 
60  char buf[32];
61  sprintf_s(buf, "ScrollWindow %d", id);
62  desc = buf;
63 }
64 
65 ScrollWindow::ScrollWindow(Screen* s, int ax, int ay, int aw, int ah, DWORD aid, DWORD s1, ActiveWindow* paw)
66 : ActiveWindow(s, ax, ay, aw, ah, aid, s1, paw)
67 {
68  captured = false;
69  dragging = false;
70  selecting = false;
72 
73  leading = 0;
75  dragdrop = false;
76  scroll_count = 0;
77  line_count = 0;
78  page_count = 0;
79  page_size = 1;
80  top_index = 0;
81  line_height = 0;
82  mouse_x = 0;
83  mouse_y = 0;
84 
85  smooth_scroll = false;
86  smooth_offset = 0;
87 
90 
91  char buf[32];
92  sprintf_s(buf, "ScrollWindow %d", id);
93  desc = buf;
94 }
95 
97 { }
98 
99 // +--------------------------------------------------------------------+
100 
101 void
103 {
105 
108 }
109 
110 // +--------------------------------------------------------------------+
111 
112 void
114 {
115  if (transparent) {
116  DrawTransparent();
117  }
118 
119  else {
121  }
122 }
123 
124 // +--------------------------------------------------------------------+
125 
126 void
128 {
129  int x = 0;
130  int y = 0;
131  int w = rect.w;
132  int h = rect.h;
133 
134  if (w < 1 || h < 1 || !shown)
135  return;
136 
138 
139  if (line_height < 1)
140  line_height = GetFont()->Height();
141  page_size = h / (line_height + leading);
142 
143  Rect ctrl_rect(x,y,w,h);
144  ctrl_rect.Deflate(BORDER_WIDTH, BORDER_WIDTH);
145 
146  if (IsScrollVisible()) {
147  ctrl_rect.w -= SCROLL_TRACK;
148  }
149 
150  DrawContent(ctrl_rect);
151  DrawScrollBar();
152 }
153 
154 // +--------------------------------------------------------------------+
155 
156 void
158 {
159  int x = 0;
160  int y = 0;
161  int w = rect.w;
162  int h = rect.h;
163 
164  if (w < 1 || h < 1 || !shown)
165  return;
166 
167  if (line_height < 1)
168  line_height = GetFont()->Height();
169  page_size = h / (line_height + leading);
170 
171  Rect ctrl_rect(x,y,w,h);
172  ctrl_rect.Deflate(BORDER_WIDTH, BORDER_WIDTH);
173 
174  if (IsScrollVisible()) {
175  ctrl_rect.w -= SCROLL_TRACK;
176  }
177 
178  DrawTransparentContent(ctrl_rect);
179  DrawScrollBar();
180 }
181 
182 // +--------------------------------------------------------------------+
183 
184 void
186 {
187  // override to do control-specific drawing
188 }
189 
190 void
192 {
193  // override (if necessary) to do control-specific drawing
194  DrawContent(ctrl_rect);
195 }
196 
197 void
199 {
200  // draw scroll bar if necessary:
201  if (IsScrollVisible()) {
202  Color save_color = back_color;
204 
205  // draw scroll track border:
207 
208  // draw top button
210  FillRect(btn_rect, back_color);
211  DrawStyleRect(btn_rect, WIN_RAISED_FRAME);
212 
213  // draw bottom button:
214  btn_rect.y = rect.h - (SCROLL_HEIGHT+BORDER_WIDTH);
215  FillRect(btn_rect, back_color);
216  DrawStyleRect(btn_rect, WIN_RAISED_FRAME);
217 
218  // draw thumb:
219  btn_rect.y = thumb_pos;
220  btn_rect.h = btn_rect.w;
221  FillRect(btn_rect, back_color);
222  DrawStyleRect(btn_rect, WIN_RAISED_FRAME);
223 
224  back_color = save_color;
225  }
226 
227  if (scrolling && scroll_count)
229 }
230 
231 // +--------------------------------------------------------------------+
232 
233 bool
235 {
236  bool vis = false;
237 
238  if (scroll_bar == SCROLL_ALWAYS ||
239  (scroll_bar == SCROLL_AUTO &&
240  line_count > page_size)) {
241  vis = true;
242  }
243 
244  return vis;
245 }
246 
248 {
249  return line_height;
250 }
251 
253 {
254  if (h >= 0)
255  line_height = h;
256 }
257 
259 {
260  return leading;
261 }
262 
263 void ScrollWindow::SetLeading(int nNewValue)
264 {
265  if (leading != nNewValue && nNewValue >= 0) {
266  leading = nNewValue;
267  }
268 }
269 
271 {
272  return dragdrop;
273 }
274 
275 void ScrollWindow::SetDragDrop(int nNewValue)
276 {
277  if (dragdrop != nNewValue && (nNewValue == 0 || nNewValue == 1)) {
278  dragdrop = nNewValue;
279  }
280 }
281 
283 {
284  return scroll_bar;
285 }
286 
288 {
289  if (scroll_bar != nNewValue) {
290  scroll_bar = nNewValue;
291  }
292 }
293 
295 {
296  return smooth_scroll;
297 }
298 
299 void ScrollWindow::SetSmoothScroll(bool bNewValue)
300 {
301  if (smooth_scroll != bNewValue) {
302  smooth_scroll = bNewValue;
304  }
305 }
306 
307 bool ScrollWindow::CanScroll(int direction, int nlines)
308 {
309  return false;
310 }
311 
313 {
314  if (index < top_index)
315  ScrollTo(index);
316 
317  else if (index > top_index+page_size)
318  ScrollTo(index-page_size);
319 }
320 
321 void ScrollWindow::Scroll(int direction, int nlines)
322 {
323  if (nlines) {
324  scrolling = direction;
325 
326  if (direction == SCROLL_UP || direction == SCROLL_PAGE_UP) {
327  top_index--;
328 
329  if (top_index < 0)
330  top_index = 0;
331 
332  else
333  scroll_count = nlines-1;
334  }
335 
336  else if (direction == SCROLL_DOWN || direction == SCROLL_PAGE_DOWN) {
337  top_index++;
338 
339  if (top_index >= line_count)
340  top_index = line_count-1;
341 
342  else
343  scroll_count = nlines-1;
344  }
345 
347  thumb_pos = TRACK_START + (int) (track_length * (double) top_index/(line_count-1));
348 
349  if (scroll_count < 1)
351  }
352 }
353 
354 void ScrollWindow::SmoothScroll(int direction, double nlines)
355 {
356  if (!smooth_scroll) {
357  Scroll(direction, (int) nlines);
358  return;
359  }
360 
361  if (direction == SCROLL_UP || direction == SCROLL_PAGE_UP) {
362  smooth_offset -= nlines;
363 
364  if (smooth_offset < 0)
365  smooth_offset = 0;
366  }
367 
368  else if (direction == SCROLL_DOWN || direction == SCROLL_PAGE_DOWN) {
369  smooth_offset += nlines;
370 
371  if (smooth_offset >= line_count)
373  }
374 
375  top_index = (int) smooth_offset;
378 }
379 
380 void ScrollWindow::ScrollTo(int index)
381 {
382  if (index >= 0 && index < line_count) {
383  top_index = index;
384  smooth_offset = index;
385 
387  }
388 }
389 
391 {
392  return top_index;
393 }
394 
396 {
397  return line_count / GetPageSize();
398 }
399 
401 {
402  return page_size;
403 }
404 
406 {
407  return rect.w-SCROLL_TRACK;
408 }
409 
411 {
412  return line_count;
413 }
414 
415 // +--------------------------------------------------------------------+
416 
417 int ScrollWindow::OnMouseMove(int x, int y)
418 {
419  bool dirty = false;
420 
421  if (captured) {
422  ActiveWindow* test = GetCapture();
423 
424  if (test != this) {
425  captured = false;
426  dirty = true;
427  }
428 
429  else {
430  if (selecting && !dragging) {
431  if (dragdrop && (x < rect.x ||
432  x > rect.x+rect.w ||
433  y < rect.y ||
434  y > rect.y+rect.h)) {
435 
436  dragging = true;
437  OnDragStart(x,y);
438  }
439  }
440 
441  if (scrolling == SCROLL_THUMB) {
442  mouse_y = y - rect.y - TRACK_START;
443 
444  int dest = (int) ((double) mouse_y/track_length * (line_count-1));
445  ScrollTo(dest);
446  dirty = true;
447  }
448  }
449  }
450 
451  return ActiveWindow::OnMouseMove(x,y);
452 }
453 
454 // +--------------------------------------------------------------------+
455 
457 {
458  if (!captured)
459  captured = SetCapture();
460 
461  mouse_x = x - rect.x;
462  mouse_y = y - rect.y;
463 
464  int x_scroll_bar = rect.w;
465 
466  if (scroll_bar == SCROLL_ALWAYS ||
467  (scroll_bar == SCROLL_AUTO &&
469  x_scroll_bar -= SCROLL_WIDTH;
470 
471  if (mouse_x < x_scroll_bar) {
473  selecting = true;
474  }
475 
476  else {
477  selecting = false;
478 
479  if (mouse_y < TRACK_START) {
481  Scroll(scrolling, 1);
483  }
484 
485  else if (mouse_y > rect.h-TRACK_START) {
487  if (top_index < line_count-1)
488  top_index++;
490  }
491 
492  else if (mouse_y < thumb_pos) {
496  }
497 
498  else if (mouse_y > thumb_pos+THUMB_HEIGHT) {
502  }
503 
504  else {
506  }
507  }
508 
509  return ActiveWindow::OnLButtonDown(x,y);
510 }
511 
512 // +--------------------------------------------------------------------+
513 
514 int ScrollWindow::OnLButtonUp(int x, int y)
515 {
516  if (captured) {
517  mouse_x = x-rect.x;
518  mouse_y = y-rect.y;
519 
520  if (dragging) {
521  if (mouse_x < 0 || mouse_x > rect.w || mouse_y < 0 || mouse_y > rect.h) {
522  FormWindow* parent_form = (FormWindow*) form;
523 
524  if (parent_form) {
525  ActiveWindow* drop_target = parent_form->FindControl(x,y);
526 
527  if (drop_target && drop_target->IsEnabled() && drop_target->IsShown())
528  drop_target->OnDragDrop(x,y,this);
529  }
530  }
531  }
532 
533  ReleaseCapture();
534  captured = false;
535 
536  Mouse::SetCursor((Mouse::CURSOR) old_cursor);
537  }
538 
539  dragging = false;
540  selecting = false;
541 
542  return ActiveWindow::OnLButtonUp(x,y);
543 }
544 
545 // +--------------------------------------------------------------------+
546 
548 {
549  if (wheel > 0)
550  Scroll(SCROLL_UP, 1);
551 
552  else if (wheel < 0)
553  Scroll(SCROLL_DOWN, 1);
554 
555  if (GetLineCount() > 0) {
556  static double scroll_time = 0;
557 
558  if (GetRealTime() - scroll_time > 0.5) {
559  scroll_time = GetRealTime();
561  }
562  }
563 
564  return ActiveWindow::OnMouseWheel(wheel);
565 }
566 
567 // +--------------------------------------------------------------------+
568 
570 {
571  int fire_select = !scrolling;
572 
573  if (scrolling == SCROLL_THUMB)
575 
576  if (fire_select)
577  return ActiveWindow::OnSelect();
578  else
579  return ActiveWindow::OnClick();
580 
581  return 0;
582 }
583 
584 // +--------------------------------------------------------------------+
585 
586 int ScrollWindow::OnKeyDown(int vk, int flags)
587 {
588  switch (vk) {
589  case VK_UP: Scroll(SCROLL_UP, 1);
591  break;
592 
593  case VK_DOWN: Scroll(SCROLL_DOWN, 1);
595  break;
596 
597  case VK_PRIOR: Scroll(SCROLL_UP, page_count);
599  break;
600 
601  case VK_NEXT: Scroll(SCROLL_DOWN, page_count);
603  break;
604 
605  case VK_HOME: EnsureVisible(0);
607  break;
608 
609  case VK_END: EnsureVisible(line_count-1);
611  break;
612 
613  default: break;
614  }
615 
616  return ActiveWindow::OnKeyDown(vk, flags);
617 }
618 
619 // +--------------------------------------------------------------------+
620 
621 int ScrollWindow::OnDragStart(int x, int y)
622 {
623  old_cursor = Mouse::SetCursor(Mouse::DRAG);
624  return ActiveWindow::OnDragStart(x,y);
625 }
626 
627 // +--------------------------------------------------------------------+
628 
629 int ScrollWindow::OnDragDrop(int x, int y, ActiveWindow* source)
630 {
631  return ActiveWindow::OnDragDrop(x,y,source);
632 }