doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RollupPanel.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "../../sys/win32/win_local.h"
33 #include "RollupPanel.h"
34 
35 // Based on original code by Johann Nadalutti
36 
37 #define RP_PGBUTTONHEIGHT 18
38 #define RP_SCROLLBARWIDTH 6
39 #define RP_GRPBOXINDENT 6
40 #define RP_SCROLLBARCOLOR RGB(150,180,180)
41 #define RP_ROLLCURSOR MAKEINTRESOURCE(32649) // see IDC_HAND (WINVER >= 0x0500)
42 
43 //Popup Menu Ids
44 #define RP_IDM_EXPANDALL 0x100
45 #define RP_IDM_COLLAPSEALL 0x101
46 #define RP_IDM_STARTITEMS 0x102
47 
50 
51 #define DEFERPOS
52 
53 /*
54 ================
55 rvRollupPanel::rvRollupPanel
56 
57 constructor
58 ================
59 */
61 {
62  mStartYPos = 0;
63  mItemHeight = 0;
64  mWindow = NULL;
65 }
66 
67 /*
68 ================
69 rvRollupPanel::~rvRollupPanel
70 
71 destructor
72 ================
73 */
75 {
76  // destroy the items
77  for ( ; mItems.Num(); )
78  {
79  _RemoveItem ( 0 );
80  }
81 }
82 
83 /*
84 ================
85 rvRollupPanel::Create
86 
87 Create the rollup panel window
88 ================
89 */
90 bool rvRollupPanel::Create ( DWORD dwStyle, const RECT& rect, HWND parent, unsigned int id )
91 {
92  WNDCLASSEX wndClass;
93  memset ( &wndClass, 0, sizeof(wndClass) );
94  wndClass.cbSize = sizeof(WNDCLASSEX);
95  wndClass.lpszClassName = "ROLLUP_PANEL";
96  wndClass.lpfnWndProc = WindowProc;
97  wndClass.hbrBackground = (HBRUSH)GetSysColorBrush ( COLOR_3DFACE );
98  wndClass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
99  wndClass.lpszMenuName = NULL;
100  wndClass.hInstance = win32.hInstance;
101  wndClass.style = CS_VREDRAW | CS_HREDRAW;
102  RegisterClassEx ( &wndClass );
103 
104  mWindow = CreateWindowEx ( WS_EX_TOOLWINDOW,
105  "ROLLUP_PANEL",
106  "",
107  dwStyle|WS_CLIPSIBLINGS,
108  rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
109  parent,
110  NULL,
111  win32.hInstance,
112  this );
113 
114  if ( !mWindow )
115  {
116  return false;
117  }
118 
119  return true;
120 }
121 
122 /*
123 ================
124 rvRollupPanel::InsertItem
125 
126 Insert and item into the rollup panel. Return -1 if an error occured
127 ================
128 */
129 int rvRollupPanel::InsertItem ( const char* caption, HWND dialog, bool autoDestroy, int index )
130 {
131  assert ( caption );
132  assert ( dialog );
133 
134  // -1 means add to the end
135  if ( index > 0 && index >= mItems.Num() )
136  {
137  index = -1;
138  }
139 
140  // Get client rect
141  RECT r;
142  GetClientRect(mWindow,&r);
143 
144  // Create the GroupBox control
145  HWND groupbox = CreateWindow ( "BUTTON", "", WS_CHILD|BS_GROUPBOX,
146  r.left, r.top, r.right-r.left, r.bottom-r.top,
147  mWindow, 0, win32.hInstance, NULL );
148 
149  // Create the expand button
150  HWND button = CreateWindow ( "BUTTON", caption, WS_CHILD|BS_AUTOCHECKBOX|BS_PUSHLIKE|BS_FLAT,
151  r.left, r.top, r.right-r.left, r.bottom-r.top,
152  mWindow, 0, win32.hInstance, NULL );
153 
154  // Change the button's font
155  SendMessage ( button, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0 );
156 
157  // Add item to the item list
158  RPITEM* item = new RPITEM;
159  item->mExpanded = false;
160  item->mEnable = true;
161  item->mDialog = dialog;
162  item->mButton = button;
163  item->mGroupBox = groupbox;
164  item->mOldDlgProc = (WNDPROC) GetWindowLong ( dialog, DWL_DLGPROC );
165  item->mOldButtonProc = (WNDPROC) GetWindowLong ( button, GWL_WNDPROC );
166  item->mAutoDestroy = autoDestroy;
167  strcpy ( item->mCaption, caption );
168 
169  if ( index < 0 )
170  {
171  index = mItems.Append ( item );
172  }
173  else
174  {
175  mItems.Insert ( item, index );
176  }
177 
178  // Store data with the dialog window in its user data
179  SetWindowLong ( dialog, GWL_USERDATA, (LONG)item );
180 
181  // Attach item to button through user data
182  SetWindowLong ( button, GWL_USERDATA, (LONG)item );
183  SetWindowLong ( button, GWL_ID, index );
184 
185  // Subclass dialog
186  SetWindowLong ( dialog, DWL_DLGPROC, (LONG)DialogProc );
187 
188  // SubClass button
189  SetWindowLong ( button, GWL_WNDPROC, (LONG)ButtonProc );
190 
191  // Update
193  RecallLayout ( );
194 
195  // One hook for all panel dialogs
196  if ( !mDialogHook )
197  {
198  mDialogHook = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId() );
199  }
200 
201  mDialogs.Append ( dialog );
202 
203  return index;
204 }
205 
206 /*
207 ================
208 rvRollupPanel::RemoveItem
209 
210 Remove the item at the given index from the rollup panel
211 ================
212 */
214 {
215  // safety check
216  if ( index >= mItems.Num() || index < 0 )
217  {
218  return;
219  }
220 
221  // remove the item
222  _RemoveItem( index );
223 
224  // update the layout
225  RecallLayout ( );
226 }
227 
228 /*
229 ================
230 rvRollupPanel::RemoveAllItems
231 
232 Remove all items from the control
233 ================
234 */
236 {
237  for ( ; mItems.Num(); )
238  {
239  _RemoveItem ( 0 );
240  }
241 
242  // update layout
243  RecallLayout ( );
244 }
245 
246 /*
247 ================
248 rvRollupPanel::_RemoveItem
249 
250 called by RemoveItem and RemoveAllItems methods to acutally remove the item
251 ================
252 */
254 {
255  RPITEM* item = mItems[index];
256 
257  // get the item rect
258  RECT ir;
259  GetWindowRect ( item->mDialog, &ir );
260 
261  // update item height
263  if ( item->mExpanded )
264  {
265  mItemHeight -= (ir.bottom-ir.top);
266  }
267 
268  // destroy windows
269  if ( item->mButton )
270  {
271  DestroyWindow ( item->mButton );
272  }
273  if ( item->mGroupBox )
274  {
275  DestroyWindow ( item->mGroupBox );
276  }
277  if ( item->mDialog && item->mAutoDestroy )
278  {
279  DestroyWindow ( item->mDialog );
280  mDialogs.Remove ( item->mDialog );
281  }
282 
283  if ( mDialogs.Num () <= 0 )
284  {
285  UnhookWindowsHookEx( mDialogHook );
286  mDialogHook = NULL;
287  }
288 
289  // finish up
290  mItems.RemoveIndex ( index );
291  delete item;
292 }
293 
294 /*
295 ================
296 rvRollupPanel::ExpandItem
297 
298 expand or collapse the item at the given index
299 ================
300 */
301 void rvRollupPanel::ExpandItem( int index, bool expand )
302 {
303  // safety check
304  if ( index >= mItems.Num() || index < 0 )
305  {
306  return;
307  }
308 
309  _ExpandItem ( mItems[index], expand );
310 
311  RecallLayout ( );
312 
313  // scroll to this page (automatic page visibility)
314  if ( expand )
315  {
316  ScrollToItem ( index, false );
317  }
318 }
319 
320 /*
321 ================
322 rvRollupPanel::ExpandItem
323 
324 expand or collapse the item at the given index
325 ================
326 */
327 void rvRollupPanel::ExpandAllItems( bool expand )
328 {
329  int i;
330 
331  // expand all items
332  for ( i=0; i < mItems.Num(); i ++ )
333  {
334  _ExpandItem ( mItems[i], expand );
335  }
336 
337  RecallLayout();
338 }
339 
340 /*
341 ================
342 rvRollupPanel::ExpandItem
343 
344 expand or collapse the item at the given index
345 ================
346 */
347 void rvRollupPanel::_ExpandItem ( RPITEM* item, bool expand )
348 {
349  // check if we need to change state
350  if ( item->mExpanded == expand || !item->mEnable )
351  {
352  return;
353  }
354 
355  RECT ir;
356  GetWindowRect ( item->mDialog, &ir );
357 
358  // Expand-collapse
359  item->mExpanded = expand;
360 
361  if ( expand )
362  {
363  mItemHeight += (ir.bottom - ir.top);
364  }
365  else
366  {
367  mItemHeight -= (ir.bottom - ir.top);
368  }
369 }
370 
371 /*
372 ================
373 rvRollupPanel::EnableItem
374 
375 enable/disable the item at the given index
376 ================
377 */
378 void rvRollupPanel::EnableItem ( int index, bool enable )
379 {
380  // safety check
381  if ( index >= mItems.Num() || index < 0 )
382  {
383  return;
384  }
385 
386  _EnableItem ( mItems[index], enable );
387  RecallLayout ( );
388 }
389 
390 /*
391 ================
392 rvRollupPanel::EnableAllItems
393 
394 enable/disable all items in the panel
395 ================
396 */
397 void rvRollupPanel::EnableAllItems ( bool enable )
398 {
399  int i;
400 
401  for ( i=0; i < mItems.Num(); i++ )
402  {
403  _EnableItem ( mItems[i], enable );
404  }
405 
406  RecallLayout ( );
407 }
408 
409 /*
410 ================
411 rvRollupPanel::_EnableItem
412 
413 Called by EnableItem and EnableAllItems to do the work of enabling/disablgin
414 the window
415 ================
416 */
417 void rvRollupPanel::_EnableItem ( RPITEM* item, bool enable )
418 {
419  // check if we need to change state
420  if ( item->mEnable == enable )
421  {
422  return;
423  }
424 
425  RECT ir;
426  GetWindowRect ( item->mDialog, &ir );
427 
428  item->mEnable = enable;
429 
430  if ( item->mExpanded )
431  {
432  mItemHeight -= (ir.bottom-ir.top);
433  item->mExpanded = false;
434  }
435 }
436 
437 /*
438 ================
439 rvRollupPanel::ScrollToItem
440 
441 Scroll a page at the top of the Rollup Panel if top = true or just ensure
442 item visibility into view if top = false
443 ================
444 */
446 {
447  // safety check
448  if ( index >= mItems.Num() || index < 0 )
449  {
450  return;
451  }
452 
453  RPITEM* item = mItems[index];
454 
455  // get rects
456  RECT r;
457  RECT ir;
458  GetWindowRect ( mWindow, &r );
459  GetWindowRect ( item->mDialog, &ir );
460 
461  // check page visibility
462  if ( top || ((ir.bottom > r.bottom) || (ir.top < r.top)))
463  {
464  // compute new mStartYPos
465  GetWindowRect( item->mButton, &ir );
466  mStartYPos -= (ir.top-r.top);
467 
468  RecallLayout();
469  }
470 }
471 
472 /*
473 ================
474 rvRollupPanel::MoveItemAt
475 
476 newIndex can be equal to -1 (move at end)
477 return -1 if an error occurs
478 ================
479 */
480 int rvRollupPanel::MoveItemAt ( int index, int newIndex )
481 {
482  if ( index == newIndex || index >= mItems.Num() || index < 0 )
483  {
484  return -1;
485  }
486 
487  // remove page from its old position
488  RPITEM* item = mItems[index];
489  mItems.RemoveIndex ( index );
490 
491  // insert at its new position
492  if ( newIndex < 0 )
493  {
494  index = mItems.Append( item );
495  }
496  else
497  {
498  mItems.Insert ( item, newIndex );
499  index = newIndex;
500  }
501 
502  RecallLayout ( );
503 
504  return index;
505 }
506 
507 /*
508 ================
509 rvRollupPanel::RecallLayout
510 
511 Update the layout of the control based on current states
512 ================
513 */
515 {
516  int bottomPagePos;
517  RECT r;
518  int posy;
519  int i;
520 
521  // check StartPosY
522  GetClientRect ( mWindow, &r );
523  bottomPagePos = mStartYPos + mItemHeight;
524 
525  if ( bottomPagePos < r.bottom-r.top )
526  {
527  mStartYPos = (r.bottom-r.top) - mItemHeight;
528  }
529  if ( mStartYPos > 0 )
530  {
531  mStartYPos = 0;
532  }
533 
534  // update layout
535 #ifdef DEFERPOS
536  HDWP hdwp;
537  hdwp = BeginDeferWindowPos ( mItems.Num() * 3 );
538 #endif
539  posy = mStartYPos;
540 
541  for ( i=0; i < mItems.Num(); i++ )
542  {
543  RPITEM* item = mItems[i];
544 
545  // enable / disable button
546  SendMessage ( item->mButton, BM_SETCHECK, (item->mEnable&item->mExpanded)?BST_CHECKED:BST_UNCHECKED, 0 );
547  EnableWindow ( item->mButton, item->mEnable );
548 
549  // Expanded
550  if ( item->mExpanded && item->mEnable )
551  {
552  RECT ir;
553  GetWindowRect ( item->mDialog, &ir );
554 
555  // update GroupBox position and size
556 #ifdef DEFERPOS
557  DeferWindowPos ( hdwp,
558 #else
559  SetWindowPos (
560 #endif
561  item->mGroupBox, 0, 2, posy,
562  (r.right-r.left)-3-RP_SCROLLBARWIDTH,
563  (ir.bottom-ir.top)+RP_PGBUTTONHEIGHT+RP_GRPBOXINDENT-4,
564  SWP_NOZORDER|SWP_SHOWWINDOW);
565 
566  //Update Dialog position and size
567 #ifdef DEFERPOS
568  DeferWindowPos ( hdwp,
569 #else
570  SetWindowPos (
571 #endif
572  item->mDialog, 0, RP_GRPBOXINDENT, posy+RP_PGBUTTONHEIGHT,
573  (r.right-r.left)-RP_SCROLLBARWIDTH-(RP_GRPBOXINDENT*2),
574  ir.bottom-ir.top, SWP_NOZORDER|SWP_SHOWWINDOW);
575 
576  //Update Button's position and size
577 #ifdef DEFERPOS
578  DeferWindowPos ( hdwp,
579 #else
580  SetWindowPos (
581 #endif
582  item->mButton, 0, RP_GRPBOXINDENT, posy,
583  (r.right-r.left)-RP_SCROLLBARWIDTH-(RP_GRPBOXINDENT*2),
584  RP_PGBUTTONHEIGHT, SWP_NOZORDER|SWP_SHOWWINDOW);
585 
586  posy += (ir.bottom-ir.top) + RP_PGBUTTONHEIGHT;
587  }
588  // collapsed
589  else
590  {
591  // update GroupBox position and size
592 #ifdef DEFERPOS
593  DeferWindowPos ( hdwp,
594 #else
595  SetWindowPos (
596 #endif
597  item->mGroupBox, 0, 2, posy,
598  (r.right-r.left)-3-RP_SCROLLBARWIDTH, 16, SWP_NOZORDER|SWP_SHOWWINDOW);
599 
600  // update Dialog position and size
601 #ifdef DEFERPOS
602  DeferWindowPos ( hdwp,
603 #else
604  SetWindowPos (
605 #endif
606  item->mDialog, 0, RP_GRPBOXINDENT, 0, 0, 0,SWP_NOZORDER|SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE);
607 
608  // update Button's position and size
609 #ifdef DEFERPOS
610  DeferWindowPos ( hdwp,
611 #else
612  SetWindowPos (
613 #endif
614  item->mButton, 0, RP_GRPBOXINDENT, posy,
615  (r.right-r.left)-RP_SCROLLBARWIDTH-(RP_GRPBOXINDENT*2),
616  RP_PGBUTTONHEIGHT, SWP_NOZORDER|SWP_SHOWWINDOW);
617 
618  posy += RP_PGBUTTONHEIGHT;
619  }
620 
621  posy += (RP_GRPBOXINDENT/2);
622 
623  }
624 
625 #ifdef DEFERPOS
626  EndDeferWindowPos ( hdwp );
627 #endif
628 
629  // update Scroll Bar
630  RECT br;
631  SetRect ( &br, r.right-RP_SCROLLBARWIDTH,r.top,r.right,r.bottom);
632  InvalidateRect( mWindow, &br, FALSE );
633  UpdateWindow ( mWindow );
634 }
635 
636 /*
637 ================
638 rvRollupPanel::GetItemIndex
639 
640 Return -1 if no matching item was found, otherwise the index of the item
641 ================
642 */
644 {
645  int i;
646 
647  //Search matching button's hwnd
648  for ( i=0; i < mItems.Num(); i++ )
649  {
650  if ( wnd == mItems[i]->mButton )
651  {
652  return i;
653  }
654  }
655 
656  return -1;
657 }
658 
659 int rvRollupPanel::GetItemIndex ( const char* caption )
660 {
661  int i;
662 
663  //Search matching button's hwnd
664  for ( i=0; i < mItems.Num(); i++ )
665  {
666  if ( !idStr::Icmp ( caption, mItems[i]->mCaption ) )
667  {
668  return i;
669  }
670  }
671 
672  return -1;
673 }
674 
675 /*
676 ================
677 rvRollupPanel::GetItem
678 
679 Return NULL if the index is invalid
680 ================
681 */
683 {
684  // safety check
685  if ( index >= mItems.Num() || index < 0 )
686  {
687  return NULL;
688  }
689 
690  return mItems[index];
691 }
692 
693 /*
694 ================
695 rvRollupPanel::DialogProc
696 
697 Dialog procedure for items
698 ================
699 */
700 LRESULT CALLBACK rvRollupPanel::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
701 {
702  RPITEM* item = (RPITEM*)GetWindowLong ( hWnd, GWL_USERDATA );
703  rvRollupPanel* _this = (rvRollupPanel*)GetWindowLong ( GetParent ( hWnd ), GWL_USERDATA );
704 
705  RECT r;
706  GetClientRect ( _this->mWindow, &r );
707 
708  if ( _this->mItemHeight > r.bottom-r.top )
709  {
710  switch (uMsg)
711  {
712  case WM_LBUTTONDOWN:
713  case WM_MBUTTONDOWN:
714  {
715  POINT pos;
716  GetCursorPos ( &pos );
717  _this->mOldMouseYPos = pos.y;
718  ::SetCapture(hWnd);
719  return 0;
720  }
721 
722  case WM_LBUTTONUP:
723  case WM_MBUTTONUP:
724  {
725  if ( ::GetCapture() == hWnd )
726  {
727  ::ReleaseCapture();
728  return 0;
729  }
730  break;
731  }
732 
733  case WM_MOUSEMOVE:
734  if ( (::GetCapture() == hWnd) && (wParam==MK_LBUTTON || wParam==MK_MBUTTON))
735  {
736  POINT pos;
737  GetCursorPos(&pos);
738  _this->mStartYPos += (pos.y-_this->mOldMouseYPos);
739  _this->RecallLayout();
740  _this->mOldMouseYPos = pos.y;
741  InvalidateRect ( _this->mWindow, NULL, TRUE );
742  return 0;
743  }
744 
745  break;
746 
747  case WM_SETCURSOR:
748  if ( (HWND)wParam == hWnd)
749  {
750  SetCursor ( LoadCursor (NULL, RP_ROLLCURSOR) );
751  return TRUE;
752  }
753  break;
754  }
755  }
756 
757  return ::CallWindowProc ( item->mOldDlgProc, hWnd, uMsg, wParam, lParam );
758 }
759 
760 /*
761 ================
762 rvRollupPanel::DialogProc
763 
764 Button procedure for items
765 ================
766 */
767 LRESULT CALLBACK rvRollupPanel::ButtonProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
768 {
769  if ( uMsg == WM_SETFOCUS )
770  {
771  return FALSE;
772  }
773 
774  RPITEM* item = (RPITEM*)GetWindowLong(hWnd, GWL_USERDATA);
775  return ::CallWindowProc( item->mOldButtonProc, hWnd, uMsg, wParam, lParam );
776 }
777 
778 /*
779 ================
780 rvRollupPanel::WindowProc
781 
782 Window procedure for rollup panel
783 ================
784 */
785 LRESULT CALLBACK rvRollupPanel::WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
786 {
787  rvRollupPanel* panel;
788  panel = (rvRollupPanel*)GetWindowLong (hWnd, GWL_USERDATA);
789 
790  switch ( uMsg )
791  {
792  case WM_CREATE:
793  {
794  LPCREATESTRUCT cs;
795 
796  // Attach the class to the window first
797  cs = (LPCREATESTRUCT) lParam;
798  panel = (rvRollupPanel*) cs->lpCreateParams;
799  SetWindowLong ( hWnd, GWL_USERDATA, (LONG)panel );
800  break;
801  }
802 
803  case WM_COMMAND:
804  panel->HandleCommand ( wParam, lParam );
805  break;
806 
807  case WM_PAINT:
808  return panel->HandlePaint ( wParam, lParam );
809 
810  case WM_SIZE:
811  return panel->HandleSize ( wParam, lParam );
812 
813  case WM_LBUTTONDOWN:
814  panel->HandleLButtonDown ( wParam, lParam );
815  break;
816 
817  case WM_LBUTTONUP:
818  panel->HandleLButtonUp ( wParam, lParam );
819  break;
820 
821  case WM_MOUSEMOVE:
822  panel->HandleMouseMove ( wParam, lParam );
823  break;
824 
825  case WM_MOUSEWHEEL:
826  panel->HandleMouseWheel ( wParam, lParam );
827  break;
828 
829  case WM_MOUSEACTIVATE:
830  panel->HandleMouseActivate ( wParam, lParam );
831  break;
832 
833  case WM_CONTEXTMENU:
834  return panel->HandleContextMenu ( wParam, lParam );
835  }
836 
837  return DefWindowProc ( hWnd, uMsg, wParam, lParam );
838 }
839 
840 /*
841 ================
842 rvRollupPanel::HandleCommand
843 
844 Handle the WM_COMMAND message
845 ================
846 */
847 int rvRollupPanel::HandleCommand ( WPARAM wParam, LPARAM lParam )
848 {
849  // popup menu command to expand or collapse pages
850  if ( LOWORD(wParam) == RP_IDM_EXPANDALL )
851  {
852  ExpandAllItems ( true );
853  }
854  else if ( LOWORD(wParam) == RP_IDM_COLLAPSEALL )
855  {
856  ExpandAllItems ( false );
857  }
858 
859  // popupMenu command to expand page
860  else if ( LOWORD(wParam) >= RP_IDM_STARTITEMS &&
861  LOWORD(wParam) < RP_IDM_STARTITEMS + GetItemCount ( ) )
862  {
863  int index = LOWORD(wParam)-RP_IDM_STARTITEMS;
864  ExpandItem ( index, !IsItemExpanded(index) );
865  }
866 
867  // button command
868  else if ( HIWORD(wParam) == BN_CLICKED )
869  {
870  int index = GetItemIndex ((HWND)lParam);
871  if ( index != -1 )
872  {
873  ExpandItem ( index, !IsItemExpanded ( index ) );
874  return 0;
875  }
876  }
877 
878  return 0;
879 }
880 
881 /*
882 ================
883 rvRollupPanel::HandlePaint
884 
885 Handle the WM_PAINT message
886 ================
887 */
888 int rvRollupPanel::HandlePaint( WPARAM wParam, LPARAM lParam )
889 {
890  HDC dc;
891  PAINTSTRUCT ps;
892  RECT r;
893  RECT br;
894  int sbPos;
895  int sbSize;
896  int clientHeight;
897 
898  dc = BeginPaint ( mWindow, &ps );
899 
900  // scrollbar
901  GetClientRect ( mWindow, &r );
902  SetRect ( &br, r.right-RP_SCROLLBARWIDTH, r.top, r.right, r.bottom );
903  DrawEdge ( dc, &br, EDGE_RAISED, BF_RECT );
904 
905  sbPos = 0;
906  sbSize = 0;
907  clientHeight = (r.bottom-r.top) - 4;
908 
909  if ( mItemHeight > (r.bottom-r.top) )
910  {
911  sbSize = clientHeight - (((mItemHeight-(r.bottom-r.top)) * clientHeight ) / mItemHeight );
912  sbPos = -(mStartYPos * clientHeight) / mItemHeight;
913  }
914  else
915  {
916  sbSize = clientHeight;
917  }
918 
919  br.left +=2;
920  br.right -=1;
921  br.top = sbPos+2;
922  br.bottom = br.top+sbSize;
923 
924  HBRUSH brush;
925  brush = CreateSolidBrush ( RP_SCROLLBARCOLOR );
926  FillRect ( dc, &br, brush );
927  DeleteObject ( brush );
928 
929  SetRect ( &r, br.left,2,br.right,br.top );
930  FillRect ( dc, &r, (HBRUSH)GetStockObject ( BLACK_BRUSH ) );
931 
932  SetRect ( &r, br.left,br.bottom,br.right,2+clientHeight );
933  FillRect ( dc, &r, (HBRUSH)GetStockObject ( BLACK_BRUSH ) );
934 
935  return 0;
936 }
937 
938 /*
939 ================
940 rvRollupPanel::HandleSize
941 
942 Handle the WM_SIZE message
943 ================
944 */
945 int rvRollupPanel::HandleSize ( WPARAM wParam, LPARAM lParam )
946 {
947  DefWindowProc ( mWindow, WM_SIZE, wParam, lParam );
948  RecallLayout();
949  return 0;
950 }
951 
952 /*
953 ================
954 rvRollupPanel::HandleLButtonDown
955 
956 Handle the WM_LBUTTONDOWN message
957 ================
958 */
959 int rvRollupPanel::HandleLButtonDown ( WPARAM wParam, LPARAM lParam )
960 {
961  RECT r;
962  RECT br;
963  POINT point;
964 
965  GetClientRect ( mWindow, &r );
966  if ( mItemHeight <= r.bottom - r.top )
967  {
968  return 0;
969  }
970 
971  point.x = LOWORD(lParam);
972  point.y = HIWORD(lParam);
973 
974  SetRect ( &br, r.right - RP_SCROLLBARWIDTH, r.top, r.right, r.bottom );
975 
976  if ( (wParam & MK_LBUTTON) && PtInRect ( &br, point ) )
977  {
978  SetCapture( mWindow );
979 
980  int clientHeight = (r.bottom-r.top) - 4;
981 
982  int sbSize = clientHeight - (((mItemHeight - (r.bottom-r.top)) * clientHeight) / mItemHeight );
983  int sbPos = -(mStartYPos * clientHeight) / mItemHeight;
984 
985  // click inside scrollbar cursor
986  if ( (point.y < (sbPos + sbSize)) && (point.y > sbPos ))
987  {
988  mSBOffset = sbPos - point.y + 1;
989  }
990  // click outside scrollbar cursor (2 cases => above or below cursor)
991  else
992  {
993  int distup = point.y - sbPos;
994  int distdown = (sbPos + sbSize) - point.y;
995 
996  if ( distup < distdown )
997  {
998  //above
999  mSBOffset = 0;
1000  }
1001  else
1002  {
1003  //below
1004  mSBOffset = -sbSize;
1005  }
1006  }
1007 
1008  // calc new m_nStartYPos from mouse pos
1009  int targetPos = point.y + mSBOffset;
1010  mStartYPos =- (targetPos * mItemHeight) / clientHeight;
1011 
1012  // update
1013  RecallLayout();
1014  }
1015 
1016  return 0;
1017 }
1018 
1019 /*
1020 ================
1021 rvRollupPanel::HandleLButtonUp
1022 
1023 Handle the WM_LBUTTONUP message
1024 ================
1025 */
1026 int rvRollupPanel::HandleLButtonUp ( WPARAM wParam, LPARAM lParam )
1027 {
1028  if ( GetCapture() == mWindow )
1029  {
1030  ReleaseCapture();
1031  }
1032 
1033  return 0;
1034 }
1035 
1036 /*
1037 ================
1038 rvRollupPanel::HandleMouseMove
1039 
1040 Handle the WM_MOUSEMOVE message
1041 ================
1042 */
1043 int rvRollupPanel::HandleMouseMove ( WPARAM wParam, LPARAM lParam )
1044 {
1045  RECT r;
1046  RECT br;
1047  POINT point;
1048 
1049  GetClientRect ( mWindow, &r );
1050  if ( mItemHeight <= r.bottom - r.top )
1051  {
1052  return 0;
1053  }
1054 
1055  point.x = LOWORD(lParam);
1056  point.y = HIWORD(lParam);
1057 
1058  SetRect ( &br, r.right - RP_SCROLLBARWIDTH, r.top, r.right, r.bottom );
1059 
1060  if ( (wParam & MK_LBUTTON) && (GetCapture() == mWindow ))
1061  {
1062  // calc new m_nStartYPos from mouse pos
1063  int clientHeight = (r.bottom-r.top) - 4;
1064  int targetPos = point.y + mSBOffset;
1065 
1066  mStartYPos =- (targetPos * mItemHeight) / clientHeight;
1067 
1068  RecallLayout ( );
1069 
1070  InvalidateRect ( mWindow, NULL, FALSE );
1071 // UpdateWindow ( mWindow );
1072  }
1073 
1074  return 0;
1075 }
1076 
1077 /*
1078 ================
1079 rvRollupPanel::HandleMouseWheel
1080 
1081 Handle the WM_MOUSEWHEEL message
1082 ================
1083 */
1084 int rvRollupPanel::HandleMouseWheel ( WPARAM wParam, LPARAM lParam )
1085 {
1086  // calc new m_nStartYPos
1087  mStartYPos += (HIWORD(wParam) / 4);
1088 
1089  RecallLayout();
1090 
1091  return 0;
1092 }
1093 
1094 /*
1095 ================
1096 rvRollupPanel::HandleMouseActivate
1097 
1098 Handle the WM_MOUSEACTIVATE message
1099 ================
1100 */
1101 int rvRollupPanel::HandleMouseActivate ( WPARAM wParam, LPARAM lParam )
1102 {
1103  SetFocus ( mWindow );
1104  return 0;
1105 }
1106 
1107 /*
1108 ================
1109 rvRollupPanel::HandleContextMenu
1110 
1111 Handle the WM_CONTEXTMENU message
1112 ================
1113 */
1114 int rvRollupPanel::HandleContextMenu ( WPARAM wParam, LPARAM lParam )
1115 {
1116  HMENU menu;
1117  int i;
1118  POINT point;
1119 
1120  menu = CreatePopupMenu ( );
1121  if ( !menu )
1122  {
1123  return 0;
1124  }
1125 
1126  point.x = LOWORD(lParam);
1127  point.y = HIWORD(lParam);
1128 
1129  AppendMenu ( menu, MF_STRING, RP_IDM_EXPANDALL, "Expand all" );
1130  AppendMenu ( menu, MF_STRING, RP_IDM_COLLAPSEALL, "Collapse all" );
1131  AppendMenu ( menu, MF_SEPARATOR, 0, "" );
1132 
1133  //Add all pages with checked style for expanded ones
1134  for ( i=0; i < mItems.Num(); i++ )
1135  {
1136  char itemName[1024];
1137  GetWindowText ( mItems[i]->mButton, itemName, 1023 );
1138  AppendMenu ( menu, MF_STRING, RP_IDM_STARTITEMS + i, itemName );
1139 
1140  if ( mItems[i]->mExpanded )
1141  {
1142  CheckMenuItem ( menu, RP_IDM_STARTITEMS + i, MF_CHECKED);
1143  }
1144 
1145  TrackPopupMenu ( menu, TPM_LEFTALIGN|TPM_LEFTBUTTON, point.x, point.y, 0, mWindow, NULL );
1146  }
1147 
1148  return 0;
1149 }
1150 
1151 /*
1152 ================
1153 rvRollupPanel::GetMsgProc
1154 
1155 Ensures normal dialog functions work in the alpha select dialog
1156 ================
1157 */
1158 LRESULT FAR PASCAL rvRollupPanel::GetMsgProc ( int nCode, WPARAM wParam, LPARAM lParam )
1159 {
1160  LPMSG lpMsg = (LPMSG) lParam;
1161 
1162  if ( nCode >= 0 && PM_REMOVE == wParam )
1163  {
1164  // Don't translate non-input events.
1165  if ( (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) )
1166  {
1167  int i;
1168  for ( i = 0; i < mDialogs.Num(); i ++ )
1169  {
1170  if ( IsDialogMessage( mDialogs[i], lpMsg) )
1171  {
1172  // The value returned from this hookproc is ignored,
1173  // and it cannot be used to tell Windows the message has been handled.
1174  // To avoid further processing, convert the message to WM_NULL
1175  // before returning.
1176  lpMsg->message = WM_NULL;
1177  lpMsg->lParam = 0;
1178  lpMsg->wParam = 0;
1179  break;
1180  }
1181  }
1182  }
1183  }
1184 
1185  return CallNextHookEx ( mDialogHook, nCode, wParam, lParam);
1186 }
1187 
1188 /*
1189 ================
1190 rvRollupPanel::AutoSize
1191 
1192 Automatically set the width of the control based on the dialogs it contains
1193 ================
1194 */
1196 {
1197  int i;
1198  int width = 0;
1199  for ( i = 0; i < mItems.Num(); i ++ )
1200  {
1201  RECT r;
1202  int w;
1203  GetWindowRect ( mItems[i]->mDialog, &r );
1204  w = (r.right-r.left)+RP_SCROLLBARWIDTH+(RP_GRPBOXINDENT*2);
1205  if ( w > width )
1206  {
1207  width = w;
1208  }
1209  }
1210 
1211  RECT cr;
1212  GetWindowRect ( mWindow, &cr );
1213  SetWindowPos ( mWindow, NULL, 0, 0, width, cr.bottom-cr.top, SWP_NOMOVE|SWP_NOZORDER );
1214 }
1215 
bool mEnable
Definition: RollupPanel.h:40
HWND mGroupBox
Definition: RollupPanel.h:38
bool IsItemExpanded(int index)
Definition: RollupPanel.h:123
char mCaption[RPITEM_MAX_NAME]
Definition: RollupPanel.h:44
void RecallLayout(void)
HWND mButton
Definition: RollupPanel.h:37
int HandleLButtonDown(WPARAM wParam, LPARAM lParam)
assert(prefInfo.fullscreenBtn)
void ExpandItem(int index, bool expand=true)
bool mExpanded
Definition: RollupPanel.h:39
int InsertItem(const char *caption, HWND dialog, bool autoDestroy, int index=-1)
void _EnableItem(RPITEM *item, bool enable)
#define RP_SCROLLBARWIDTH
Definition: RollupPanel.cpp:38
int HandlePaint(WPARAM wParam, LPARAM lParam)
bool mAutoDestroy
Definition: RollupPanel.h:41
int HandleMouseMove(WPARAM wParam, LPARAM lParam)
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
void EnableItem(int index, bool enabled=true)
void RemoveItem(int index)
static LRESULT CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
void EnableAllItems(bool enable=true)
DWORD
Definition: win_qgl.cpp:61
static LRESULT FAR PASCAL GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
void _ExpandItem(RPITEM *item, bool expand)
virtual ~rvRollupPanel(void)
Definition: RollupPanel.cpp:74
void AutoSize(void)
static LRESULT CALLBACK ButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
int i
Definition: process.py:33
rvRollupPanel(void)
Definition: RollupPanel.cpp:60
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
int Icmp(const char *text) const
Definition: Str.h:667
int GetItemCount(void)
Definition: RollupPanel.h:118
#define RP_GRPBOXINDENT
Definition: RollupPanel.cpp:39
int HandleMouseActivate(WPARAM wParam, LPARAM lParam)
int HandleMouseWheel(WPARAM wParam, LPARAM lParam)
static HHOOK mDialogHook
Definition: RollupPanel.h:115
idList< RPITEM * > mItems
Definition: RollupPanel.h:101
#define RP_IDM_EXPANDALL
Definition: RollupPanel.cpp:44
#define RP_ROLLCURSOR
Definition: RollupPanel.cpp:41
GLuint index
Definition: glext.h:3476
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
HWND mDialog
Definition: RollupPanel.h:36
#define NULL
Definition: Lib.h:88
WNDPROC mOldDlgProc
Definition: RollupPanel.h:42
#define RP_IDM_COLLAPSEALL
Definition: RollupPanel.cpp:45
static idList< HWND > mDialogs
Definition: RollupPanel.h:114
#define RP_SCROLLBARCOLOR
Definition: RollupPanel.cpp:40
#define FAR
Definition: jmorecfg.h:205
int HandleContextMenu(WPARAM wParam, LPARAM lParam)
GLenum GLsizei width
Definition: glext.h:2846
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void)
bool Create(DWORD dwStyle, const RECT &rect, HWND parent, unsigned int id)
Definition: RollupPanel.cpp:90
GLdouble GLdouble GLdouble top
Definition: qgl.h:273
int HandleCommand(WPARAM wParam, LPARAM lParam)
int Insert(const type &obj, int index=0)
Definition: List.h:679
long LONG
int Append(const type &obj)
Definition: List.h:646
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
int MoveItemAt(int index, int newIndex)
int Num(void) const
Definition: List.h:265
bool RemoveIndex(int index)
Definition: List.h:849
MFnDagNode * GetParent(MFnDagNode *joint)
Definition: maya_main.cpp:350
int HandleSize(WPARAM wParam, LPARAM lParam)
int GetItemIndex(const char *caption)
void ExpandAllItems(bool expand=true)
void _RemoveItem(int index)
RPITEM * GetItem(int index)
void RemoveAllItems(void)
void ScrollToItem(int index, bool top=true)
#define FALSE
Definition: mprintf.c:70
#define TRUE
Definition: mprintf.c:69
HINSTANCE hInstance
Definition: win_local.h:102
if(!ValidDisplayID(prefInfo.prefDisplayID)) prefInfo.prefDisplayID
#define RP_PGBUTTONHEIGHT
Definition: RollupPanel.cpp:37
Win32Vars_t win32
Definition: win_main.cpp:65
int HandleLButtonUp(WPARAM wParam, LPARAM lParam)
#define DEFERPOS
Definition: RollupPanel.cpp:51
#define RP_IDM_STARTITEMS
Definition: RollupPanel.cpp:46
bool Remove(const type &obj)
Definition: List.h:878
WNDPROC mOldButtonProc
Definition: RollupPanel.h:43