doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GEWorkspace.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/rc/guied_resource.h"
33 #include "../../renderer/tr_local.h"
34 #include "../../sys/win32/win_local.h"
35 #include "../../ui/DeviceContext.h"
36 #include "../../ui/EditWindow.h"
37 #include "../../ui/ListWindow.h"
38 #include "../../ui/BindWindow.h"
39 #include "../../ui/RenderWindow.h"
40 #include "../../ui/ChoiceWindow.h"
41 
42 #include "GEApp.h"
43 #include "GEItemPropsDlg.h"
44 #include "GEItemScriptsDlg.h"
45 
46 // Modifiers
47 #include "GEModifierGroup.h"
48 #include "GEMoveModifier.h"
49 #include "GESizeModifier.h"
50 #include "GEStateModifier.h"
51 #include "GEZOrderModifier.h"
52 #include "GEInsertModifier.h"
53 #include "GEHideModifier.h"
54 #include "GEDeleteModifier.h"
55 
56 static float g_ZoomScales[rvGEWorkspace::ZOOM_MAX] = { 0, 0.25f, 0.33f, 0.50f, 0.66f, 1.0f, 1.5f, 2.0f, 3.0f };
57 
58 static const int ID_GUIED_SELECT_FIRST = 9800;
59 static const int ID_GUIED_SELECT_LAST = 9900;
60 
62 
63 rvGEWorkspace::rvGEWorkspace ( rvGEApp* app ) : mApplication ( app )
64 {
65  mWnd = 0;
66  mInterface = 0;
67  mZoom = ZOOM_100;
68  mScrollHorz = false;
69  mScrollVert = false;
70  mModified = false;
71  mNew = false;
72  mDragScroll = false;
74  mFilename = "guis/Untitled.gui";
76  mHandCursor = LoadCursor ( app->GetInstance(), MAKEINTRESOURCE(IDC_GUIED_HAND) );
77  mDontAdd = false;
78 
79  mSelections.SetWorkspace ( this );
80 }
81 
83 {
84  // Make sure all the wrappers get cleaned up
86 
87  DestroyCursor ( mHandCursor );
88 
89  delete mInterface;
90 }
91 
92 /*
93 ================
94 rvGEWorkspace::CleanupEnumProc
95 
96 Window enumeration procedure that deletes all the wrapper classes
97 ================
98 */
100 {
101  bool result;
102 
103  if ( !wrapper )
104  {
105  return true;
106  }
107 
108  result = wrapper->EnumChildren ( CleanupEnumProc, data );
109 
110  // Cleanup the window wrapper
111  delete wrapper;
112 
113  return result;
114 }
115 
116 /*
117 ================
118 rvGEWorkspace::GetZoomScale
119 
120 Returns the scale of the current zoom level
121 ================
122 */
124 {
125  return g_ZoomScales [ mZoom ];
126 }
127 
128 /*
129 ================
130 rvGEWorkspace::Attach
131 
132 Attaches the workspace to the given window. This is usually done after the
133 window is created and the file has been loaded.
134 ================
135 */
136 bool rvGEWorkspace::Attach ( HWND wnd )
137 {
138  assert ( wnd );
139 
140  mWnd = wnd;
141 
142  // Initialize the pixel format for this window
143  SetupPixelFormat ( );
144 
145  // Jam the workspace pointer into the userdata window long so
146  // we can retrieve the workspace from the window later
147  SetWindowLong ( mWnd, GWL_USERDATA, (LONG) this );
148 
149  UpdateTitle ( );
150 
151  return true;
152 }
153 
154 /*
155 ================
156 rvGEWorkspace::Detach
157 
158 Detaches the workspace from the window it is currently attached to
159 ================
160 */
162 {
163  assert ( mWnd );
164 
165  SetWindowLong ( mWnd, GWL_USERDATA, 0 );
166  mWnd = NULL;
167 }
168 
169 /*
170 ================
171 rvGEWorkspace::SetupPixelFormat
172 
173 Setup the pixel format for the opengl context
174 ================
175 */
177 {
178  HDC hDC = GetDC ( mWnd );
179  bool result = true;
180 
181  int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd);
182  if (pixelFormat > 0)
183  {
184  if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL)
185  {
186  result = false;
187  }
188  }
189  else
190  {
191  result = false;
192  }
193 
194  ReleaseDC ( mWnd, hDC );
195 
196  return result;
197 }
198 
199 /*
200 ================
201 rvGEWorkspace::RenderGrid
202 
203 Renders the grid on top of the user interface
204 ================
205 */
207 {
208  float x;
209  float y;
210  float step;
212 
213  // See if the grid is off before rendering it
215  {
216  return;
217  }
218 
219  qglEnable(GL_BLEND);
220  qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
221 
222  qglColor4f ( color[0], color[1], color[2], 0.5f );
223 
224  qglBegin ( GL_LINES );
225  step = mApplication->GetOptions().GetGridWidth ( ) * g_ZoomScales[mZoom];
226  for ( x = mRect.x + mRect.w; x >= mRect.x ; x -= step )
227  {
228  qglVertex2f ( x, mRect.y );
229  qglVertex2f ( x, mRect.y + mRect.h );
230  }
231  step = mApplication->GetOptions().GetGridHeight ( ) * g_ZoomScales[mZoom];
232  for ( y = mRect.y + mRect.h; y >= mRect.y ; y -= step )
233  {
234  qglVertex2f ( mRect.x, y );
235  qglVertex2f ( mRect.x + mRect.w, y );
236  }
237  qglEnd ( );
238 
239  qglDisable(GL_BLEND);
240  qglColor3f ( color[0], color[1], color[2] );
241 
242  qglBegin ( GL_LINES );
243  step = mApplication->GetOptions().GetGridWidth ( ) * g_ZoomScales[mZoom];
244  for ( x = mRect.x + mRect.w; x >= mRect.x ; x -= step * 4 )
245  {
246  qglVertex2f ( x, mRect.y );
247  qglVertex2f ( x, mRect.y + mRect.h );
248  }
249  step = mApplication->GetOptions().GetGridHeight ( ) * g_ZoomScales[mZoom];
250  for ( y = mRect.y + mRect.h; y >= mRect.y ; y -= step * 4 )
251  {
252  qglVertex2f ( mRect.x, y );
253  qglVertex2f ( mRect.x + mRect.w, y );
254  }
255  qglEnd ( );
256 }
257 
258 /*
259 ================
260 rvGEWorkspace::Render
261 
262 Renders the workspace to the given DC
263 ================
264 */
266 {
267  int front;
268  int back;
269  float scale;
270 
271  scale = g_ZoomScales[mZoom];
272 
273  // Switch GL contexts to our dc
274  if (!qwglMakeCurrent( hdc, win32.hGLRC ))
275  {
276  common->Printf("ERROR: wglMakeCurrent failed.. Error:%i\n", qglGetError());
277  common->Printf("Please restart Q3Radiant if the Map view is not working\n");
278  return;
279  }
280 
281  // Prepare the view and clear it
285  qglClearColor ( 0.75f, 0.75f, 0.75f, 0 );
286 
287  qglDisable(GL_DEPTH_TEST);
288  qglDisable(GL_CULL_FACE);
289  qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
290 
291  // Render the workspace below
292  glMatrixMode(GL_PROJECTION);
293  glLoadIdentity();
294  qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1);
295  glMatrixMode(GL_MODELVIEW);
296  glLoadIdentity();
297 
299  qglBegin ( GL_QUADS );
300  qglVertex2f ( mRect.x, mRect.y );
301  qglVertex2f ( mRect.x + mRect.w, mRect.y );
302  qglVertex2f ( mRect.x + mRect.w, mRect.y + mRect.h );
303  qglVertex2f ( mRect.x, mRect.y + mRect.h );
304  qglEnd ( );
305 
306  // Prepare the renderSystem view to draw the GUI in
307  viewDef_t viewDef;
308  memset ( &viewDef, 0, sizeof(viewDef) );
309  tr.viewDef = &viewDef;
314  tr.viewDef->scissor.x1 = 0;
315  tr.viewDef->scissor.y1 = 0;
316  tr.viewDef->scissor.x2 = mRect.w;
317  tr.viewDef->scissor.y2 = mRect.h;
318  tr.viewDef->isEditor = true;
320 
321  // Draw the gui
322  mInterface->Redraw ( 0 ); // eventLoop->Milliseconds() );
323 
324  // We are done using the renderSystem now
325  renderSystem->EndFrame( &front, &back );
326 
327  if ( mApplication->GetActiveWorkspace ( ) == this )
328  {
330  }
331 
332  // Prepare the viewport for drawing selections, etc.
335 // qglDisable(GL_BLEND);
336  qglDisable(GL_CULL_FACE);
337 
340  glMatrixMode(GL_PROJECTION);
341  glLoadIdentity();
342  qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1);
343  glMatrixMode(GL_MODELVIEW);
344  glLoadIdentity();
345 
346  RenderGrid ( );
347 
348  mSelections.Render ( );
349 
350  qglFinish ( );
351  qwglSwapBuffers(hdc);
352 
354  qglEnable( GL_CULL_FACE);
355 }
356 
357 /*
358 ================
359 rvGEWorkspace::UpdateTitle
360 
361 Updates the window title with the name of the file and the zoom level and weither its open or not
362 ================
363 */
365 {
366  // Set the window title based on the current filename
367  SetWindowText ( mWnd, va("%s%s (%d%%)", idStr(mFilename).StripPath ( ).c_str( ), mModified?"*":"", (int) (g_ZoomScales[mZoom] * 100)) );
368 
369  gApp.GetStatusBar().SetZoom ( (int)(g_ZoomScales[mZoom] * 100.0f) );
370 }
371 
372 /*
373 ================
374 rvGEWorkspace::UpdateRectangle
375 
376 Updates the rectangle (not counting scrolling)
377 ================
378 */
379 void rvGEWorkspace::UpdateRectangle ( bool useScroll )
380 {
381  RECT rcClient;
382  float x;
383  float y;
384  float scale;
385 
386  scale = g_ZoomScales[mZoom];
387 
388  // Grab the current client rectangle of the window and cache off the width and height
389  GetClientRect ( mWnd, &rcClient );
390  mWindowWidth = rcClient.right - rcClient.left;
391  mWindowHeight = rcClient.bottom - rcClient.top;
392 
393  // The workspace is always centered in the window
394  x = mRect.x = mWindowWidth / 2 - (SCREEN_WIDTH * scale) / 2;
395  y = mRect.y = mWindowHeight / 2 - (SCREEN_HEIGHT * scale) / 2;
396  mRect.w = (SCREEN_WIDTH * scale);
397  mRect.h = (SCREEN_HEIGHT * scale);
398 
399  // When using the scroll position offset the rectangle based on the scrollbar positions
400  if ( useScroll )
401  {
402  // Adjust the start of the rectangle for the scroll positiond
403  mRect.y -= (float)GetScrollPos ( mWnd, SB_VERT ) / 1000.0f;
404  mRect.x -= (float)GetScrollPos ( mWnd, SB_HORZ ) / 1000.0f;
405  }
406 }
407 
408 /*
409 ================
410 rvGEWorkspace::Scroll
411 
412 Adjusts the given scrollbar by the given offset
413 ================
414 */
415 void rvGEWorkspace::Scroll ( int scrollbar, int offset )
416 {
417  SCROLLINFO si;
418 
419  if ( scrollbar == SB_HORZ && !mScrollHorz )
420  {
421  return;
422  }
423  else if ( scrollbar == SB_VERT && !mScrollVert )
424  {
425  return;
426  }
427 
428  // Get all the vertial scroll bar information
429  si.cbSize = sizeof (si);
430  si.fMask = SIF_ALL;
431 
432  // Save the position for comparison later on
433  GetScrollInfo ( mWnd, scrollbar, &si);
434 
435  si.nPos += (1000 * offset);
436  if ( si.nPos < si.nMin ) si.nPos = si.nMin;
437  if ( si.nPos > si.nMax ) si.nPos = si.nMax;
438 
439  si.fMask = SIF_POS;
440  SetScrollInfo (mWnd, scrollbar, &si, TRUE);
441  GetScrollInfo (mWnd, scrollbar, &si);
442 
443  UpdateRectangle ( );
444 }
445 
446 int rvGEWorkspace::HandleScroll ( int scrollbar, WPARAM wParam, LPARAM lParam )
447 {
448  SCROLLINFO si;
449 
450  // Get all the vertial scroll bar information
451  si.cbSize = sizeof (si);
452  si.fMask = SIF_ALL;
453 
454  // Save the position for comparison later on
455  GetScrollInfo ( mWnd, scrollbar, &si);
456 
457  switch (LOWORD (wParam))
458  {
459  // user clicked left or up arrow
460  case SB_LINELEFT:
461  si.nPos -= 1000;
462  break;
463 
464  // user clicked right or down arrow
465  case SB_LINERIGHT:
466  si.nPos += 1000;
467  break;
468 
469  // user clicked shaft left of the scroll box
470  case SB_PAGELEFT:
471  si.nPos -= si.nPage;
472  break;
473 
474  // user clicked shaft right of the scroll box
475  case SB_PAGERIGHT:
476  si.nPos += si.nPage;
477  break;
478 
479  // user dragged the scroll box
480  case SB_THUMBTRACK:
481  si.nPos = si.nTrackPos;
482  break;
483 
484  default :
485  break;
486  }
487 
488  // Set the position and then retrieve it. Due to adjustments
489  // by Windows it may not be the same as the value set.
490  si.fMask = SIF_POS;
491  SetScrollInfo (mWnd, scrollbar, &si, TRUE);
492  GetScrollInfo (mWnd, scrollbar, &si);
493 
494  UpdateRectangle ( );
495 
496  return 0;
497 }
498 
499 /*
500 ================
501 rvGEWorkspace::UpdateScrollbars
502 
503 Updates the states and the ranges of the scrollbars as well as the rectangle
504 ================
505 */
507 {
508  SCROLLINFO info;
509 
510  // First update the rectangle without applying scroll positions so
511  // we know the real sizes and coordinates
512  UpdateRectangle ( false );
513 
514  // Setup the veritcal scrollbar
515  info.cbSize = sizeof(info);
516  info.fMask = SIF_RANGE|SIF_PAGE;
517  info.nMax = (mRect.h - mWindowHeight + 10) * 1000 / 2;
518  info.nMin = -info.nMax;
519  info.nPage = (int)((float)info.nMax * (float)((float)mWindowHeight / mRect.h));
520  info.nMax += info.nPage;
521 
522  // If there is something to scroll then turn on the vertical scroll bar
523  // if its not on and update the scroll info.
524  if ( info.nMax > 0 )
525  {
526  if ( !mScrollVert )
527  {
528  mScrollVert = true;
529  ShowScrollBar ( mWnd, SB_VERT, mScrollVert );
530  }
531  SetScrollInfo ( mWnd, SB_VERT, &info, TRUE );
532  }
533  // Nothing to scroll, turn off the scrollbar if its on.
534  else if ( mScrollVert )
535  {
536  mScrollVert = false;
537  SetScrollPos ( mWnd, SB_VERT, 0, FALSE );
538  ShowScrollBar ( mWnd, SB_VERT, mScrollVert );
539  }
540 
541  // Setup the horizontal scrollbar
542  info.nMax = (mRect.w - mWindowWidth + 10) * 1000 / 2;
543  info.nMin = -info.nMax;
544  info.nPage = (int)((float)info.nMax * (float)((float)mWindowWidth / mRect.w));
545  info.nMax += info.nPage;
546 
547  // If there is something to scroll then turn on the vertical scroll bar
548  // if its not on and update the scroll info.
549  if ( info.nMax > 0 )
550  {
551  if ( !mScrollHorz )
552  {
553  mScrollHorz = true;
554  ShowScrollBar ( mWnd, SB_HORZ, mScrollHorz );
555  }
556 
557  SetScrollInfo ( mWnd, SB_HORZ, &info, TRUE );
558  }
559  // Nothing to scroll, turn off the scrollbar if its on.
560  else if ( mScrollHorz )
561  {
562  mScrollHorz = false;
563  SetScrollPos ( mWnd, SB_HORZ, 0, FALSE );
564  ShowScrollBar ( mWnd, SB_HORZ, mScrollHorz );
565  }
566 
567  // Need to update the rectangle again to take the scrollbar changes into account
568  UpdateRectangle ( true );
569 }
570 
571 /*
572 ================
573 rvGEWorkspace::UpdateCursor
574 
575 Called to update the cursor when the mouse is within the workspace window
576 ================
577 */
579 {
580  switch ( type )
581  {
583  SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW) ) );
584  break;
585 
587  SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZEALL) ) );
588  break;
589 
592  SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZEWE ) ) );
593  break;
594 
597  SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZENS ) ) );
598  break;
599 
602  SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZENESW ) ) );
603  break;
604 
607  SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_SIZENWSE ) ) );
608  break;
609  }
610 }
611 
612 void rvGEWorkspace::UpdateCursor ( float x, float y )
613 {
614  idVec2 point;
616 
617  // First convert the worspace coord to a window coord
618  point = WorkspaceToWindow ( idVec2( x, y ) );
619 
620  // See if it hits anything
621  type = mSelections.HitTest ( point.x, point.y );
622 
623  // If it hits something then use it to update the cursor
624  if ( rvGESelectionMgr::HT_NONE != type )
625  {
626  UpdateCursor ( type );
627  }
628  else
629  {
630  SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) );
631  }
632 }
633 
635 {
637  {
638  POINT point;
639  idVec2 cursor;
640 
641  GetCursorPos ( &point );
642  cursor.Set ( point.x, point.y );
643  WindowToWorkspace ( cursor );
644 
645  UpdateCursor ( cursor.x, cursor.y );
646  }
647  else
648  {
650  }
651 }
652 
653 /*
654 ================
655 rvGEWorkspace::HandleMessage
656 
657 Handles window messages to the workspace
658 ================
659 */
660 void rvGEWorkspace::HandleMessage ( UINT msg, WPARAM wParam, LPARAM lParam )
661 {
662  switch ( msg )
663  {
664  case WM_CLOSE:
665  {
666 
667  if ( IsModified ( ) )
668  {
669  if ( IDYES == gApp.MessageBox ( va("Save changes to the document \"%s\" before closing?", GetFilename() ), MB_YESNO|MB_ICONQUESTION ) )
670  {
671  SendMessage ( mApplication->GetMDIFrame(), WM_COMMAND, MAKELONG(ID_GUIED_FILE_SAVE,0), 0 );
672  }
673  }
674 
675 
679  break;
680  }
681 
682  case WM_CAPTURECHANGED:
683  if ( (HWND)lParam != mWnd )
684  {
685  mDragScroll = false;
687  }
688  break;
689 
690  case WM_SETCURSOR:
691  {
692  POINT point;
693  idVec2 cursor;
694  GetCursorPos ( &point );
695  cursor.Set ( point.x, point.y );
696  WindowToWorkspace ( cursor );
698  {
699  UpdateCursor ( cursor.x, cursor.y );
700  }
701  else
702  {
704  }
705  break;
706  }
707 
708  case WM_MOUSEWHEEL:
709  if ( (short)HIWORD(wParam) > 0 )
710  {
711  ZoomIn ( );
712  }
713  else if ( (short)HIWORD(wParam) < 0 )
714  {
715  ZoomOut ( );
716  }
717  break;
718 
719  case WM_MOUSEMOVE:
720  HandleMouseMove ( wParam, lParam );
721  break;
722 
723  case WM_MBUTTONDOWN:
724  HandleMButtonDown ( wParam, lParam );
725  break;
726 
727  case WM_MBUTTONUP:
728  HandleMButtonUp ( wParam, lParam );
729  break;
730 
731  case WM_LBUTTONDOWN:
732  HandleLButtonDown ( wParam, lParam );
733  break;
734 
735  case WM_LBUTTONUP:
736  HandleLButtonUp ( wParam, lParam );
737  break;
738 
739  case WM_LBUTTONDBLCLK:
740  HandleLButtonDblClk ( wParam, lParam );
741  break;
742 
743  case WM_INITMENUPOPUP:
744  SendMessage ( mApplication->GetMDIFrame(), msg, wParam, lParam );
745  break;
746 
747  case WM_COMMAND:
748  HandleCommand ( wParam, lParam );
749  break;
750 
751  case WM_RBUTTONDOWN:
752  HandleRButtonDown ( wParam, lParam );
753  break;
754 
755  case WM_SIZE:
757  break;
758 
759  case WM_VSCROLL:
760  HandleScroll ( SB_VERT, wParam, lParam );
761  break;
762 
763  case WM_HSCROLL:
764  HandleScroll ( SB_HORZ, wParam, lParam );
765  break;
766 
767  case WM_KEYDOWN:
768  HandleKeyDown ( wParam, lParam );
769  break;
770  }
771 }
772 /*
773 ================
774 rvGEWorkspace::HandleCommand
775 
776 Handles command messages destined for the workspace window. This is for
777 special workspace commands, any unhandled commands are forwarded to the main window
778 ================
779 */
780 int rvGEWorkspace::HandleCommand ( WPARAM wParam, LPARAM lParam )
781 {
782  // Select command
783  if ( LOWORD(wParam) >= ID_GUIED_SELECT_FIRST && LOWORD(wParam) <= ID_GUIED_SELECT_LAST )
784  {
785  idWindow* window = mSelectMenu[LOWORD(wParam)-ID_GUIED_SELECT_FIRST];
786  rvGEWindowWrapper* wrapper = rvGEWindowWrapper::GetWrapper ( window );
787 
788  // Handle multi select as well
789  if ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 )
790  {
791  if ( wrapper->IsSelected ( ) )
792  {
793  mSelections.Remove ( window );
794  }
795  else
796  {
797  mSelections.Add ( window );
798  }
799  }
800  else
801  {
802  mSelections.Set ( window );
803  }
804  }
805 
806  return SendMessage ( mApplication->GetMDIFrame(), WM_COMMAND, wParam, lParam );
807 }
808 
809 /*
810 ================
811 rvGEWorkspace::HandleMButtonDown
812 
813 Handles the middle mouse down message in the workspace
814 ================
815 */
816 int rvGEWorkspace::HandleMButtonDown ( WPARAM wParam, LPARAM lParam )
817 {
819  {
820  return 0;
821  }
822 
823  mDragPoint.Set ( LOWORD(lParam), HIWORD(lParam) );
824  mDragScroll = true;
825  SetCursor ( mHandCursor );
826  SetCapture ( mWnd );
827 
829 
830  return 0;
831 }
832 
833 /*
834 ================
835 rvGEWorkspace::HandleMButtonUp
836 
837 Handles the middle mouse up message in the workspace
838 ================
839 */
840 int rvGEWorkspace::HandleMButtonUp ( WPARAM wParam, LPARAM lParam )
841 {
842  if ( mDragScroll )
843  {
844  mDragScroll = false;
845  ReleaseCapture ( );
846  }
847 
848  return 0;
849 }
850 
851 /*
852 ================
853 rvGEWorkspace::HandleRButtonDown
854 
855 Handles the left mouse down message in the workspace
856 ================
857 */
858 int rvGEWorkspace::HandleRButtonDown ( WPARAM wParam, LPARAM lParam )
859 {
860  POINT point = { LOWORD(lParam), HIWORD(lParam) };
861  HMENU menu;
862 
863  // Add the select menu
864  mSelectMenu.Clear ( );
865 
866  // Cache where the menu is being brought up so we can
867  // figure out which windows are under the point
868  mSelectMenuPos[0] = point.x;
869  mSelectMenuPos[1] = point.y;
871 
872  // Build a list of all the windows under the menu point
874 
875  // Add the desktop window always
877 
878  //
879  menu = GetSubMenu ( LoadMenu ( mApplication->GetInstance(), MAKEINTRESOURCE(IDR_GUIED_ITEM_POPUP) ), 0 );
880 
881  HMENU popup = CreatePopupMenu ( );
882 
883  int i;
884  for ( i = 0; i < mSelectMenu.Num(); i ++ )
885  {
887  AppendMenu ( popup, MF_STRING|MF_ENABLED|(wrapper->IsSelected()?MF_CHECKED:0), ID_GUIED_SELECT_FIRST + i, mSelectMenu[i]->GetName() );
888  }
889 
890  InsertMenu ( menu, 1, MF_POPUP|MF_BYPOSITION, (LONG) popup, "Select" );
891 
892  // Bring up the popup menu
893  ClientToScreen ( mWnd, &point );
894  TrackPopupMenu ( menu, TPM_RIGHTBUTTON|TPM_LEFTALIGN, point.x, point.y, 0, mWnd, NULL );
895 
896  DestroyMenu ( popup );
897  DestroyMenu ( menu );
898 
899  return 0;
900 }
901 
902 /*
903 ================
904 rvGEWorkspace::HandleLButtonDown
905 
906 Handles the left mouse down message in the workspace
907 ================
908 */
909 int rvGEWorkspace::HandleLButtonDown ( WPARAM wParam, LPARAM lParam )
910 {
911  if ( mDragScroll )
912  {
913  return 0;
914  }
915 
916  idVec2 point ( LOWORD(lParam), HIWORD(lParam) );
917  WindowToWorkspace ( point );
918 
919  // Make sure whatever modifications get generated cant be merged into whats already there
921 
922  mDragPoint.Set ( LOWORD(lParam), HIWORD(lParam) );
924  mDragX = true;
925  mDragY = true;
926 
927  // If we have selections then start a drag
928  if ( mSelections.Num ( ) )
929  {
931  }
932 
933  rvGEWindowWrapper* wrapper;
935 
936  idWindow* window = wrapper->WindowFromPoint ( point.x, point.y );
937 
938  // dissallow selection of the desktop.
939  if ( gApp.GetOptions().GetIgnoreDesktopSelect() && window == mInterface->GetDesktop ( ) )
940  {
941  window = NULL;
942  }
943 
945  {
946  if ( window )
947  {
948  bool selected;
949 
950  selected = mSelections.IsSelected ( window );
951 
952  if ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 )
953  {
954  if ( !selected )
955  {
956  mSelections.Add ( window );
958  }
959  else
960  {
961  mSelections.Remove ( window );
962  }
963  }
964  else if ( !selected && mDragType == rvGESelectionMgr::HT_NONE )
965  {
966  mSelections.Set ( window );
968  }
969  }
970  else
971  {
972  mSelections.Clear ( );
973  }
974  }
975 
976  if ( mSelections.IsExpression ( ) )
977  {
979  }
980  // Windows capture
981  else if ( mDragType != rvGESelectionMgr::HT_NONE )
982  {
983  SetCapture ( mWnd );
984  }
985 
987 
988  return 0;
989 }
990 
991 /*
992 ================
993 rvGEWorkspace::HandleLButtonUp
994 
995 Handles the left mouse up message in the workspace
996 ================
997 */
998 int rvGEWorkspace::HandleLButtonUp ( WPARAM wParam, LPARAM lParam )
999 {
1001  {
1002  ReleaseCapture ( );
1004 
1005  // Update the transformer
1007  }
1008 
1009  // No more dragging
1011 
1012  return 0;
1013 }
1014 
1015 /*
1016 ================
1017 rvGEWorkspace::HandleLButtonDblClk
1018 
1019 Handle a double click by opening properties
1020 ================
1021 */
1022 int rvGEWorkspace::HandleLButtonDblClk ( WPARAM wParam, LPARAM lParam )
1023 {
1025  return 0;
1026 }
1027 
1028 /*
1029 ================
1030 rvGEWorkspace::HandleMouseMove
1031 
1032 Handles the moving of the mouse for dragging and cursor updating
1033 ================
1034 */
1035 int rvGEWorkspace::HandleMouseMove ( WPARAM wParam, LPARAM lParam )
1036 {
1037  idVec2 cursor;
1038 
1039  cursor.Set ( (short)LOWORD(lParam), (short)HIWORD(lParam) );
1040 
1041  // Convert the window point to the workspace before updating the
1042  // cursor with the position
1043  WindowToWorkspace ( cursor );
1044 
1045  // Scrolling the window around
1046  if ( mDragScroll )
1047  {
1048  Scroll ( SB_HORZ, mDragPoint.x - cursor.x );
1049  Scroll ( SB_VERT, mDragPoint.y - cursor.y );
1050 
1051  SetCursor ( mHandCursor );
1052 
1053  mDragPoint = cursor;
1054 
1055  return 0;
1056  }
1057 
1058  // If not dragging then just update the cursor and return
1060  {
1061  UpdateCursor ( cursor.x, cursor.y );
1062  return 0;
1063  }
1064 
1065  // Dont allow a drag move start until the button has been down for 100 ms or so
1067  {
1068  return 0;
1069  }
1070 
1071  // Handle grid snapping
1072  if ( gApp.GetOptions().GetGridSnap ( ) )
1073  {
1074  cursor.x = (float)(((int)cursor.x + gApp.GetOptions().GetGridWidth()/2) / gApp.GetOptions().GetGridWidth() * gApp.GetOptions().GetGridWidth());
1075  cursor.y = (float)(((int)cursor.y + gApp.GetOptions().GetGridWidth()/2) / gApp.GetOptions().GetGridWidth() * gApp.GetOptions().GetGridWidth());
1076  }
1077 
1078  // If the cursor hasnt moved then there is nothing to update with the drag
1079  if ( (int) cursor.x == (int) mDragPoint.x && (int) cursor.y == (int) mDragPoint.y )
1080  {
1081  return 0;
1082  }
1083 
1084  switch ( mDragType )
1085  {
1087  AddModifierMove ( "Move", cursor.x - mDragPoint.x, cursor.y - mDragPoint.y, mApplication->GetOptions().GetGridSnap ( ) );
1088  break;
1089 
1091  AddModifierSize ( "Size", 0, 0, 0, cursor.y - mDragPoint.y, mApplication->GetOptions().GetGridSnap ( ) );
1092  break;
1093 
1095  AddModifierSize ( "Size", 0, cursor.y - mDragPoint.y, 0, 0, mApplication->GetOptions().GetGridSnap ( ) );
1096  break;
1097 
1099  AddModifierSize ( "Size", 0, 0, cursor.x - mDragPoint.x, 0, mApplication->GetOptions().GetGridSnap ( ) );
1100  break;
1101 
1103  AddModifierSize ( "Size", cursor.x - mDragPoint.x, 0, 0, 0, mApplication->GetOptions().GetGridSnap ( ) );
1104  break;
1105 
1107  AddModifierSize ( "Size", cursor.x - mDragPoint.x, cursor.y - mDragPoint.y, 0, 0, mApplication->GetOptions().GetGridSnap ( ) );
1108  break;
1109 
1111  AddModifierSize ( "Size", 0, cursor.y - mDragPoint.y, cursor.x - mDragPoint.x, 0, mApplication->GetOptions().GetGridSnap ( ) );
1112  break;
1113 
1115  AddModifierSize ( "Size", cursor.x - mDragPoint.x, 0, 0, cursor.y - mDragPoint.y, mApplication->GetOptions().GetGridSnap ( ) );
1116  break;
1117 
1119  AddModifierSize ( "Size", 0, 0, cursor.x - mDragPoint.x, cursor.y - mDragPoint.y, mApplication->GetOptions().GetGridSnap ( ) );
1120  break;
1121  }
1122 
1123  UpdateCursor ( mDragType );
1124 
1125  // If the x coordinate has changed then update it
1126  if ( (int)cursor.x != (int)mDragPoint.x && mDragX )
1127  {
1128  mDragPoint.x = cursor.x;
1129  }
1130 
1131  // If the y coordinate has changed then update it
1132  if ( (int)cursor.y != (int)mDragPoint.y && mDragY )
1133  {
1134  mDragPoint.y = cursor.y;
1135  }
1136 
1137  return 0;
1138 }
1139 
1140 /*
1141 ================
1142 rvGEWorkspace::HandleKeyDown
1143 
1144 Handles the the pressing of a key
1145 ================
1146 */
1147 int rvGEWorkspace::HandleKeyDown ( WPARAM wParam, LPARAM lParam )
1148 {
1149  bool shift = (GetAsyncKeyState ( VK_SHIFT ) & 0x8000) ? true : false;
1150 
1151  switch ( wParam )
1152  {
1153  case VK_LEFT:
1154  if ( shift )
1155  {
1156  AddModifierSizeNudge ( -1, 0, false );
1157  }
1158  else
1159  {
1160  AddModifierMoveNudge ( -1, 0, false );
1161  }
1162  break;
1163 
1164  case VK_RIGHT:
1165  if ( shift )
1166  {
1167  AddModifierSizeNudge ( 1, 0, false );
1168  }
1169  else
1170  {
1171  AddModifierMoveNudge ( 1, 0, false );
1172  }
1173  break;
1174 
1175  case VK_DOWN:
1176  if ( shift )
1177  {
1178  AddModifierSizeNudge ( 0, 1, false );
1179  }
1180  else
1181  {
1182  AddModifierMoveNudge ( 0, 1, false );
1183  }
1184  break;
1185 
1186  case VK_UP:
1187  if ( shift )
1188  {
1189  AddModifierSizeNudge ( 0, -1, false );
1190  }
1191  else
1192  {
1193  AddModifierMoveNudge ( 0, -1, false );
1194  }
1195  break;
1196 
1197  case VK_ESCAPE:
1198  mSelections.Clear ( );
1200  break;
1201  }
1202 
1203  return 0;
1204 }
1205 
1206 /*
1207 ================
1208 rvGEWorkspace::WindowToWorkspace
1209 
1210 Converts the given coordinates in windows space to the workspace's coordinates.
1211 ================
1212 */
1214 {
1215  point.x = (point.x - mRect.x) / mRect.w * SCREEN_WIDTH;
1216  point.y = (point.y - mRect.y) / mRect.h * SCREEN_HEIGHT;
1217 
1218  return point;
1219 }
1220 
1222 {
1223  rect.x = (rect.x - mRect.x) / mRect.w * SCREEN_WIDTH;
1224  rect.y = (rect.y - mRect.y) / mRect.h * SCREEN_HEIGHT;
1225  rect.w = rect.w / mRect.w * SCREEN_WIDTH;
1226  rect.h = rect.h / mRect.h * SCREEN_HEIGHT;
1227 
1228  return rect;
1229 }
1230 
1231 /*
1232 ================
1233 rvGEWorkspace::WindowToWorkspace
1234 
1235 Converts the given workspace coordinates to the windows coordinates.
1236 ================
1237 */
1239 {
1240  point.x = mRect.x + (point.x / SCREEN_WIDTH * mRect.w);
1241  point.y = mRect.y + (point.y / SCREEN_HEIGHT * mRect.h);
1242 
1243  return point;
1244 }
1245 
1247 {
1248  rect.x = mRect.x + (rect.x / SCREEN_WIDTH * mRect.w);
1249  rect.y = mRect.y + (rect.y / SCREEN_HEIGHT * mRect.h);
1250  rect.w = rect.w / SCREEN_WIDTH * mRect.w;
1251  rect.h = rect.h / SCREEN_HEIGHT * mRect.h;
1252 
1253  return rect;
1254 }
1255 
1256 /*
1257 ================
1258 rvGEWorkspace::ZoomIn
1259 
1260 Zooms the workspace in by one zoom level
1261 ================
1262 */
1264 {
1265  mZoom = mZoom + 1;
1266  if ( mZoom >= ZOOM_MAX )
1267  {
1268  mZoom = ZOOM_MAX - 1;
1269  }
1270 
1271  UpdateScrollbars ( );
1272  UpdateTitle ( );
1273 
1274  InvalidateRect ( mWnd, NULL, FALSE );
1275 
1276  return (EZoomLevel)mZoom;
1277 }
1278 
1279 /*
1280 ================
1281 rvGEWorkspace::ZoomOut
1282 
1283 Zooms the workspace out by one level
1284 ================
1285 */
1287 {
1288  mZoom--;
1289  if ( mZoom <= ZOOM_MIN )
1290  {
1291  mZoom = ZOOM_MIN + 1;
1292  }
1293 
1294  UpdateScrollbars ( );
1295  UpdateTitle ( );
1296 
1297  InvalidateRect ( mWnd, NULL, FALSE );
1298 
1299  return (EZoomLevel)mZoom;
1300 }
1301 
1302 /*
1303 ================
1304 rvGEWorkspace::CreateModifier
1305 
1306 Creates a new modifier of the given type for the given window. This function is called
1307 specifically from the add modifiers function with the variable args list forwarded.
1308 ================
1309 */
1311 {
1312  rvGEModifier* mod;
1313 
1314  switch ( type )
1315  {
1316  case MOD_DELETE:
1317  mod = new rvGEDeleteModifier ( "Delete", window );
1318  break;
1319 
1320  case MOD_HIDE:
1321  mod = new rvGEHideModifier ( "Hide", window, true );
1322  break;
1323 
1324  case MOD_UNHIDE:
1325  mod = new rvGEHideModifier ( "Hide", window, false );
1326  break;
1327 
1328  case MOD_SEND_BACKWARD:
1329  mod = new rvGEZOrderModifier ( "Send Backward", window, rvGEZOrderModifier::ZO_BACKWARD );
1330  break;
1331 
1332  case MOD_SEND_BACK:
1333  mod = new rvGEZOrderModifier ( "Send to Back", window, rvGEZOrderModifier::ZO_BACK );
1334  break;
1335 
1336  case MOD_BRING_FORWARD:
1337  mod = new rvGEZOrderModifier ( "Bring Forward", window, rvGEZOrderModifier::ZO_FORWARD );
1338  break;
1339 
1340  case MOD_BRING_FRONT:
1341  mod = new rvGEZOrderModifier ( "Bring to Front", window, rvGEZOrderModifier::ZO_FRONT );
1342  break;
1343 
1344  default:
1345  mod = NULL;
1346  break;
1347  }
1348 
1349  return mod;
1350 }
1351 
1352 /*
1353 ================
1354 rvGEWorkspace::AddModifiers
1355 
1356 Add the specific modifier for the given window
1357 ================
1358 */
1360 {
1361  va_list args;
1362 
1363  va_start(args,type) ;
1364  mModifiers.Append ( CreateModifier ( type, window, args ) );
1365  va_end (args) ;
1366 
1367  SetModified ( true );
1368 }
1369 
1371 {
1372  va_list args;
1373 
1374  // Nothing to move if there is no selection
1375  if ( !mSelections.Num ( ) )
1376  {
1377  return;
1378  }
1379  // More than one selection requires a modifier group
1380  else if ( mSelections.Num ( ) > 1 )
1381  {
1382  rvGEModifierGroup* group = new rvGEModifierGroup;
1383  int i;
1384 
1385  for ( i = 0; i < mSelections.Num(); i ++ )
1386  {
1387  va_start(args,type);
1388  group->Append ( CreateModifier ( type, mSelections[i], args ) );
1389  va_end (args);
1390  }
1391 
1392  mModifiers.Append ( group );
1393  }
1394  // Single modifier
1395  else
1396  {
1397  va_start(args,type) ;
1398  mModifiers.Append ( CreateModifier ( type, mSelections[0], args ) );
1399  va_end (args) ;
1400  }
1401 
1402  SetModified ( true );
1403 }
1404 
1406 {
1407  rvGEWorkspace* workspace;
1408 
1409  workspace = (rvGEWorkspace*) data;
1410  assert ( workspace );
1411 
1412  if ( !wrapper )
1413  {
1414  return true;
1415  }
1416 
1417  wrapper->EnumChildren ( BuildSelectMenuEnumProc, data );
1418 
1419  if ( wrapper->IsDeleted ( ) || wrapper->IsHidden ( ) )
1420  {
1421  return true;
1422  }
1423 
1424  if ( wrapper->GetScreenRect ( ).Contains ( workspace->mSelectMenuPos[0], workspace->mSelectMenuPos[1] ) )
1425  {
1426  workspace->mSelectMenu.Append ( wrapper->GetWindow ( ));
1427  }
1428 
1429  return true;
1430 }
1431 
1433 {
1434  rvGEModifierGroup* group = (rvGEModifierGroup*) data;
1435 
1436  wrapper->EnumChildren ( ShowAllEnumProc, data );
1437 
1438  if ( wrapper->IsHidden ( ) )
1439  {
1440  group->Append ( new rvGEHideModifier ( "Show Hidden", wrapper->GetWindow ( ), false ) );
1441  }
1442 
1443  return true;
1444 }
1445 
1447 {
1448  rvGEModifierGroup* group = new rvGEModifierGroup;
1449 
1450  rvGEWindowWrapper::GetWrapper( mInterface->GetDesktop ( ) )->EnumChildren ( ShowAllEnumProc, group );
1451 
1452  if ( !group->GetCount ( ) )
1453  {
1454  delete group;
1455  }
1456  else
1457  {
1458  mModifiers.Append ( group );
1459  }
1460 
1462 }
1463 
1465 {
1467  mSelections.Clear ( );
1469 }
1470 
1471 /*
1472 ================
1473 rvGEWorkspace::NewWindow
1474 
1475 Create a new window
1476 ================
1477 */
1479 {
1481  rvGEWindowWrapper* wrapper;
1482  int count;
1483  idStr baseName;
1484 
1485  switch ( type )
1486  {
1488  window = new idWindow ( mInterface->GetDesktop()->GetDC(), mInterface );
1489  break;
1490 
1492  window = new idBindWindow ( mInterface->GetDesktop()->GetDC(), mInterface );
1493  break;
1494 
1496  window = new idRenderWindow ( mInterface->GetDesktop()->GetDC(), mInterface );
1497  break;
1498 
1500  window = new idChoiceWindow ( mInterface->GetDesktop()->GetDC(), mInterface );
1501  break;
1502 
1504  window = new idEditWindow ( mInterface->GetDesktop()->GetDC(), mInterface );
1505  break;
1506 
1507  default:
1508  assert ( false );
1509  return NULL;
1510  }
1511 
1512  baseName = state ? state->GetString("name","unnamed") : "unnamed";
1513  baseName.StripQuotes ( );
1514 
1515  count = 0;
1516  if ( mInterface->GetDesktop()->FindChildByName ( baseName ) )
1517  {
1518  count = 1;
1519  while ( 1 )
1520  {
1521  drawWin_t* dw = mInterface->GetDesktop()->FindChildByName ( va("%s%d",baseName.c_str(),count) );
1522  if ( !dw )
1523  {
1524  break;
1525  }
1526  assert ( dw->win );
1527  wrapper = rvGEWindowWrapper::GetWrapper ( dw->win );
1528  if ( wrapper && wrapper->IsDeleted ( ) )
1529  {
1530  break;
1531  }
1532  count++;
1533  }
1534  }
1535 
1536  idStr winName;
1537  idStr winTemplate;
1538 
1539  if ( count )
1540  {
1541  winName = va("%s%d", baseName.c_str(), count );
1542  }
1543  else
1544  {
1545  winName = baseName;
1546  }
1547  winTemplate = winName + " { }";
1548 
1550  window->Parse ( &src );
1551 
1552  wrapper = rvGEWindowWrapper::GetWrapper ( window );
1553 
1554  if ( state )
1555  {
1556  wrapper->SetState ( *state );
1557  }
1558 
1559  wrapper->SetStateKey ( "name", winName );
1560  wrapper->Finish ( );
1561 
1562  SetModified ( true );
1563 
1564 
1565  return window;
1566 }
1567 
1569 {
1570  idWindow* window;
1571  idDict state;
1572 
1573  state.Set ( "rect", "0,0,100,100" );
1574  state.Set ( "visible", "1" );
1575 
1576  window = NewWindow ( &state, type );
1577  assert ( window );
1578 
1579  mModifiers.Append ( new rvGEInsertModifier ( "New", window, mInterface->GetDesktop(), NULL ) );
1580 
1581  mSelections.Set ( window );
1585 
1586  return window;
1587 }
1588 
1590 {
1591  if ( !mSelections.Num ( ) || mSelections.Num() > 1 )
1592  {
1593  return false;
1594  }
1595 
1596  idDict dict;
1597  if ( GEItemPropsDlg_DoModal ( mWnd, mSelections[0], dict ) )
1598  {
1599  mModifiers.Append ( new rvGEStateModifier ( "Item Properties", mSelections[0], dict ) );
1600  SetModified ( true );
1601  }
1602 
1606 
1607  return true;
1608 }
1609 
1611 {
1613  {
1614  gApp.GetNavigator().Refresh ( );
1615  SetModified ( true );
1616  }
1617 
1618  return true;
1619 }
1620 
1622 {
1625 }
1626 
1628 {
1631 }
1632 
1634 {
1637 }
1638 
1640 {
1643 }
1644 
1645 /*
1646 ================
1647 rvGEWorkspace::MakeSelectedSameSize
1648 
1649 Align the selected items to the first one using the given align type
1650 ================
1651 */
1652 void rvGEWorkspace::MakeSelectedSameSize ( bool changeWidth, bool changeHeight )
1653 {
1654  rvGEModifierGroup* group;
1655  idRectangle rectTo;
1656  int i;
1657 
1658  group = new rvGEModifierGroup ( );
1659 
1661 
1662  for ( i = 1; i < mSelections.Num(); i ++ )
1663  {
1664  idRectangle rectFrom;
1665  float width = 0;
1666  float height = 0;
1667 
1669 
1670  if ( changeWidth )
1671  {
1672  width = rectTo.w - rectFrom.w;
1673  }
1674 
1675  if ( changeHeight )
1676  {
1677  height = rectTo.h - rectFrom.h;
1678  }
1679 
1680  group->Append ( new rvGESizeModifier ( "Make Same Size", mSelections[i], 0, 0, width, height ) );
1681  }
1682 
1683  mModifiers.Append ( group );
1684 
1685  // Cant merge alignments
1687 
1688  SetModified ( true );
1689 }
1690 
1691 /*
1692 ================
1693 rvGEWorkspace::AlignSelected
1694 
1695 Align the selected items to the first one using the given align type
1696 ================
1697 */
1699 {
1700  static const char* alignNames[]={"Lefts","Centers","Rights","Tops","Middles","Bottoms" };
1701  int i;
1702  idStr modName;
1703  rvGEModifierGroup* group;
1704 
1705  assert ( mSelections.Num() > 1 );
1706 
1707  modName = "Align " + idStr(alignNames[align]);
1708 
1709  group = new rvGEModifierGroup ( );
1710 
1711  idRectangle rectTo;
1713 
1714  // Everything gets aligned to the first selection so run
1715  // through all other selections and move them.
1716  for ( i = 1; i < mSelections.Num(); i ++ )
1717  {
1718  float x;
1719  float y;
1720  idRectangle rectFrom;
1721 
1723 
1724  switch ( align )
1725  {
1726  case ALIGN_LEFTS:
1727  x = rectTo[0] - rectFrom[0];
1728  y = 0;
1729  break;
1730 
1731  case ALIGN_RIGHTS:
1732  x = (rectTo[0]+rectTo[2]) - (rectFrom[0]+rectFrom[2]);
1733  y = 0;
1734  break;
1735 
1736  case ALIGN_CENTERS:
1737  x = (rectTo[0]+rectTo[2]/2) - (rectFrom[0]+rectFrom[2]/2);
1738  y = 0;
1739  break;
1740 
1741  case ALIGN_TOPS:
1742  y = rectTo[1] - rectFrom[1];
1743  x = 0;
1744  break;
1745 
1746  case ALIGN_BOTTOMS:
1747  x = 0;
1748  y = (rectTo[1]+rectTo[3]) - (rectFrom[1]+rectFrom[3]);
1749  break;
1750 
1751  case ALIGN_MIDDLES:
1752  x = 0;
1753  y = (rectTo[1]+rectTo[3]/2) - (rectFrom[1]+rectFrom[3]/2);
1754  break;
1755 
1756  default:
1757  assert ( false );
1758  break;
1759  }
1760 
1761  group->Append ( new rvGEMoveModifier ( modName, mSelections[i], x, y ) );
1762  }
1763 
1764  mModifiers.Append ( group );
1765 
1766  // Cant merge alignments
1768 
1769  SetModified ( true );
1770 }
1771 
1772 /*
1773 ================
1774 rvGEWorkspace::AddModifierMove
1775 
1776 Adds a move modifier with the given offsets
1777 ================
1778 */
1779 void rvGEWorkspace::AddModifierMove ( const char* modName, float x, float y, bool snap )
1780 {
1781  idRectangle scaleRect;
1782  idRectangle newRect;
1783 
1784  scaleRect = mSelections.GetRect ( );
1785  WindowToWorkspace ( scaleRect );
1786  newRect = scaleRect;
1787  newRect.x += x;
1788  newRect.y += y;
1789 
1790  if ( snap )
1791  {
1792  gApp.GetOptions ().SnapRectToGrid ( newRect, true, true, false, false );
1793  }
1794 
1795  rvGEModifierGroup* group = new rvGEModifierGroup;
1796  for ( int i = 0; i < mSelections.Num(); i ++ )
1797  {
1798  if ( !mSelections[i]->GetParent ( ) )
1799  {
1800  continue;
1801  }
1802 
1803  // IF the parent window is being moved around as well then dont move this one.
1805  {
1806  // We still need the modifier there so the selection can be restored and
1807  // so the rectangle gets updated
1808  group->Append ( new rvGEMoveModifier ( modName, mSelections[i], 0, 0 ) );
1809  continue;
1810  }
1811 
1812  group->Append ( new rvGEMoveModifier ( modName, mSelections[i], newRect.x-scaleRect.x, newRect.y-scaleRect.y ) );
1813  }
1814 
1815  mModifiers.Append ( group );
1816 
1817  SetModified ( true );
1818 }
1819 
1820 /*
1821 ================
1822 rvGEWorkspace::AddModifierSize
1823 
1824 Adds a size modifier with the given offsets
1825 ================
1826 */
1827 void rvGEWorkspace::AddModifierSize ( const char* modName, float l, float t, float r, float b, bool snap )
1828 {
1829  idRectangle scaleRect;
1830  idRectangle sizeRect;
1831  idRectangle newRect;
1832 
1833  scaleRect = mSelections.GetRect ( );
1834  WindowToWorkspace ( scaleRect );
1835  newRect = scaleRect;
1836  newRect.x += l;
1837  newRect.y += t;
1838  newRect.w += (r - l);
1839  newRect.h += (b - t);
1840 
1841  // Restrict sizing below 1 width
1842  if ( newRect.w <= 1 )
1843  {
1844  newRect.x = newRect.x - (l ? (1 - newRect.w) : 0);
1845  mDragPoint.x = newRect.x;
1846  newRect.w = 1;
1847  mDragX = false;
1848  }
1849  else
1850  {
1851  mDragX = true;
1852  }
1853 
1854  // Restrict sizing below 1 height
1855  if ( newRect.h <= 1 )
1856  {
1857  newRect.y = newRect.y - (t ? (1 - newRect.h) : 0);
1858  mDragPoint.y = newRect.y;
1859  newRect.h = 1;
1860  mDragY = false;
1861  }
1862  else
1863  {
1864  mDragY = true;
1865  }
1866 
1867  if ( snap )
1868  {
1869  gApp.GetOptions ().SnapRectToGrid ( newRect, l != 0.0f, t != 0.0f, r != 0.0f, b != 0.0f );
1870  }
1871 
1872  rvGEModifierGroup* group = new rvGEModifierGroup;
1873  for ( int i = 0; i < mSelections.Num(); i ++ )
1874  {
1876 
1877  l = (newRect.x + ((sizeRect.x - scaleRect.x) / scaleRect.w) * newRect.w) - sizeRect.x;
1878  t = (newRect.y + ((sizeRect.y - scaleRect.y) / scaleRect.h) * newRect.h) - sizeRect.y;
1879  r = (sizeRect.w / scaleRect.w * newRect.w) - sizeRect.w + l;
1880  b = (sizeRect.h / scaleRect.h * newRect.h) - sizeRect.h + t;
1881 
1882  // This is sorta crufty but needs to be done. When a parent is being sized at the same
1883  // time as a child you will get double movement because the child is relative to the parent. Therefore
1884  // we need to subtract out the closest parents sizing.
1885  idWindow* parent = mSelections[i];
1886  while ( NULL != (parent = parent->GetParent ( ) ) )
1887  {
1888  rvGEWindowWrapper* pwrapper = rvGEWindowWrapper::GetWrapper ( parent );
1889  float offset;
1890 
1891  if ( !pwrapper->IsSelected ( ) )
1892  {
1893  continue;
1894  }
1895 
1896  sizeRect = pwrapper->GetScreenRect ( );
1897 
1898  // Subtract out the left and right modifications
1899  offset = ((newRect.x + ((sizeRect.x - scaleRect.x) / scaleRect.w) * newRect.w) - sizeRect.x);
1900  l -= offset;
1901  r -= offset;
1902 
1903  // Subtract out the top and bottom modifications
1904  offset = ((newRect.y + ((sizeRect.y - scaleRect.y) / scaleRect.h) * newRect.h) - sizeRect.y);
1905  t -= offset;
1906  b -= offset;
1907 
1908  break;
1909  }
1910 
1911  group->Append ( new rvGESizeModifier ( modName, mSelections[i], l, t, r, b ) );
1912  }
1913 
1914  mModifiers.Append ( group );
1915 
1916  SetModified ( true );
1917 }
1918 
1919 /*
1920 ================
1921 rvGEWorkspace::MakeSelectedAChild
1922 
1923 Makes the selected windows a child of the first selected window
1924 ================
1925 */
1927 {
1928  rvGEModifierGroup* group;
1929  int i;
1930 
1931  if ( !rvGEWindowWrapper::GetWrapper ( mSelections[0] )->CanHaveChildren ( ) )
1932  {
1933  gApp.MessageBox ( "Cannot add children to an htmlDef item", MB_OK|MB_ICONERROR );
1934  return;
1935  }
1936 
1937  group = new rvGEModifierGroup;
1938 
1939  for ( i = 1; i < mSelections.Num(); i ++ )
1940  {
1941  if ( mSelections[i]->GetParent ( ) == mSelections[0] )
1942  {
1943  continue;
1944  }
1945 
1946  if ( !mSelections[i]->GetParent ( ) )
1947  {
1948  continue;
1949  }
1950 
1951  group->Append ( new rvGEInsertModifier ( "Make Child", mSelections[i], mSelections[0], NULL ) );
1952  }
1953 
1954  mModifiers.Append ( group );
1955 
1956  // Navigator needs an update since the ordering has changed
1957  gApp.GetNavigator().Update ( );
1958 
1959  SetModified ( true );
1960 }
1961 
1962 void rvGEWorkspace::Copy ( void )
1963 {
1964  int i;
1965 
1966  // Clear the current clipboard
1967  for ( i = 0; i < mClipboard.Num(); i ++ )
1968  {
1969  delete mClipboard[i];
1970  }
1971 
1972  mClipboard.Clear ( );
1973 
1974  for ( i = 0; i < mSelections.Num(); i ++ )
1975  {
1977  assert ( wrapper );
1978 
1980  item->mStateDict = wrapper->GetStateDict ( );
1981  item->mScriptDict = wrapper->GetScriptDict ( );
1982  item->mVarDict = wrapper->GetVariableDict ( );
1983 
1984  item->mStateDict.Set ( "windowType", rvGEWindowWrapper::WindowTypeToString ( wrapper->GetWindowType ( ) ) );
1985 
1986  mClipboard.Append ( item );
1987  }
1988 }
1989 
1991 {
1992  int i;
1993 
1994  rvGEModifierGroup* group = new rvGEModifierGroup;
1995 
1996  mSelections.Clear ( );
1997 
1998  for ( i = 0; i < mClipboard.Num(); i ++ )
1999  {
2000  idDict state;
2002 
2003  state.Copy ( mClipboard[i]->mStateDict );
2004  type = rvGEWindowWrapper::StringToWindowType ( state.GetString ( "windowType", "windowDef" ) );
2005  state.Delete ( "windowType" );
2006 
2007  idWindow* window = NewWindow ( &state, type );
2008  group->Append ( new rvGEInsertModifier ( "Paste", window, mInterface->GetDesktop(), NULL ) );
2009  mSelections.Add ( window );
2010 
2011  rvGEWindowWrapper::GetWrapper ( window )->GetScriptDict ( ) = mClipboard[i]->mScriptDict;
2012  rvGEWindowWrapper::GetWrapper ( window )->GetVariableDict ( ) = mClipboard[i]->mVarDict;
2013  }
2014 
2015  mModifiers.Append ( group );
2016 
2018 
2019  SetModified ( true );
2020 }
2021 
2023 {
2024  AddModifiers ( MOD_HIDE );
2025  mSelections.Clear ( );
2027 }
2028 
2030 {
2033 }
2034 
2036 {
2037  AddModifiers ( window, MOD_HIDE );
2039 }
2040 
2042 {
2043  AddModifiers ( window, MOD_UNHIDE );
2045 }
2046 
2047 /*
2048 ================
2049 rvGEWorkspace::SetModified
2050 
2051 Sets the modified state of the window and if source control is enabled it
2052 will attempt to check out the file
2053 ================
2054 */
2056 {
2057  if ( mModified != mod )
2058  {
2059 
2060  mModified = mod;
2061  UpdateTitle ( );
2062 
2063  }
2064 }
bool IsSelected(idWindow *window)
void RenderGrid(void)
byte color[4]
Definition: MegaTexture.cpp:54
int HandleCommand(WPARAM wParam, LPARAM lParam)
void Paste(void)
virtual void EndFrame(int *frontEndMsec, int *backEndMsec)=0
#define qglScissor
Definition: qgl_linked.h:280
Definition: GEApp.h:73
assert(prefInfo.fullscreenBtn)
void Scroll(int scrollbar, int offset)
void Add(idWindow *window, bool expand=true)
rvGESelectionMgr::EHitTest mDragType
Definition: GEWorkspace.h:234
void UpdateScrollbars(void)
EZoomLevel ZoomIn(void)
void Delete(const char *key)
Definition: Dict.cpp:496
int GetGridHeight(void)
Definition: GEOptions.h:218
bool GEItemScriptsDlg_DoModal(HWND parent, idWindow *window)
bool EditSelectedScripts(void)
#define qglDisable
Definition: qgl_linked.h:92
void AddModifierShowAll(void)
static bool CleanupEnumProc(rvGEWindowWrapper *wrapper, void *data)
Definition: GEWorkspace.cpp:99
idWindow * WindowFromPoint(float x, float y, bool visibleOnly=true)
float y
Definition: Vector.h:55
void SetZoom(int zoom)
Definition: GEStatusBar.h:62
short x2
Definition: tr_local.h:55
bool Attach(HWND wnd)
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
bool GetGridSnap(void)
Definition: GEOptions.h:228
backEndCounters_t pc
Definition: tr_local.h:642
HGLRC hGLRC
Definition: win_local.h:122
int HandleLButtonDblClk(WPARAM wParam, LPARAM lParam)
#define qglClearColor
Definition: qgl_linked.h:41
idStr & StripQuotes(void)
Definition: Str.cpp:665
void HandleMessage(UINT msg, WPARAM wParam, LPARAM lParam)
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:4804
int Length(void) const
Definition: Str.h:702
void SetWorkspace(rvGEWorkspace *workspace)
void SnapRectToGrid(idRectangle &rect, bool snapLeft=true, bool snapTop=true, bool snapWidth=true, bool snapHeight=true)
Definition: GEOptions.cpp:155
drawWin_t * FindChildByName(const char *name)
Definition: Window.cpp:2573
void Set(idWindow *)
void Remove(idWindow *)
virtual void Redraw(int time)
GLenum GLint GLint y
Definition: glext.h:2849
EWindowType GetWindowType(void)
const int SCREEN_HEIGHT
Definition: RenderSystem.h:154
idRenderSystem * renderSystem
int Sys_Milliseconds(void)
case const int
Definition: Callbacks.cpp:52
int HandleLButtonDown(WPARAM wParam, LPARAM lParam)
void SendSelectedToBack(void)
void Update(void)
#define ID_GUIED_FILE_SAVE
void AddModifierSizeNudge(float w, float h, bool snap)
Definition: GEWorkspace.h:308
#define qglBegin
Definition: qgl_linked.h:33
rvGEWorkspace(rvGEApp *app)
Definition: GEWorkspace.cpp:63
void SetModified(bool mod)
const int GLS_DEFAULT
Definition: tr_local.h:1047
#define qglGetError
Definition: qgl_linked.h:131
case const float
Definition: Callbacks.cpp:62
void AddModifiers(EModifierType type,...)
void SendSelectedBackward(void)
static bool ShowAllEnumProc(rvGEWindowWrapper *wrapper, void *data)
rvGEProperties & GetProperties(void)
Definition: GEApp.h:153
const char * GetFilename(void)
Definition: GEWorkspace.h:273
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
short x1
Definition: tr_local.h:55
static const char * WindowTypeToString(EWindowType type)
rvGEWorkspace * GetActiveWorkspace(HWND *retwnd=NULL)
Definition: GEApp.cpp:167
static EWindowType StringToWindowType(const char *string)
EHitTest HitTest(float x, float y)
GLuint src
Definition: glext.h:5390
#define qglViewport
Definition: qgl_linked.h:364
void Set(const char *key, const char *value)
Definition: Dict.cpp:275
GLenum GLint x
Definition: glext.h:2849
HWND GetMDIFrame(void)
Definition: GEApp.h:178
void UpdateTitle(void)
virtual void BeginFrame(int windowWidth, int windowHeight)=0
int i
Definition: process.py:33
GLintptr offset
Definition: glext.h:3113
HINSTANCE GetInstance(void)
Definition: GEApp.h:168
Boolean result
void SetTriangles(int tris)
Definition: GEStatusBar.h:71
#define qglEnable
Definition: qgl_linked.h:101
void Copy(const idDict &other)
Definition: Dict.cpp:70
idDict & GetStateDict(void)
rvGEApp gApp
Definition: guied.cpp:41
list l
Definition: prepare.py:17
backEndState_t backEnd
Definition: tr_backend.cpp:35
int HandleScroll(int scrollbar, WPARAM wParam, LPARAM lParam)
idWindow * win
Definition: SimpleWindow.h:37
rvGETransformer & GetTransformer(void)
Definition: GEApp.h:158
void BringSelectedForward(void)
void SetWorkspace(rvGEWorkspace *workspace)
rvGEModifier * CreateModifier(EModifierType type, idWindow *window, va_list args)
rvGEModifierStack mModifiers
Definition: GEWorkspace.h:231
idVec4 & GetWorkspaceColor(void)
Definition: GEOptions.h:233
GLuint GLuint GLsizei count
Definition: glext.h:2845
ESourceControlState mSourceControlState
Definition: GEWorkspace.h:257
Definition: Vector.h:52
bool GEItemPropsDlg_DoModal(HWND parent, idWindow *window, idDict &dict)
idRectangle mRect
Definition: GEWorkspace.h:221
rvGEOptions & GetOptions(void)
Definition: GEApp.h:163
float GetZoomScale(void)
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
Definition: Vector.h:808
void SetWorkspace(rvGEWorkspace *workspace)
idDict & GetScriptDict(void)
idRectangle & GetClientRect(void)
bool Append(rvGEModifier *mod)
void Update(void)
rvGEApp * GetApplication(void)
Definition: GEWorkspace.h:318
int HandleMouseMove(WPARAM wParam, LPARAM lParam)
float y
Definition: Rectangle.h:37
renderView_t renderView
Definition: tr_local.h:370
idCommon * common
Definition: Common.cpp:206
Definition: Dict.h:65
#define NULL
Definition: Lib.h:88
bool IsModified(void)
Definition: GEWorkspace.h:278
HDC hDC
Definition: wglext.h:383
idDeviceContext * GetDC(void)
Definition: Window.h:206
void Render(HDC hDC)
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
#define qglOrtho
Definition: qgl_linked.h:218
#define qglEnd
Definition: qgl_linked.h:103
idRectangle & GetScreenRect(void)
idDict & GetVariableDict(void)
#define qglColor3f
Definition: qgl_linked.h:50
void DeleteSelected(void)
virtual bool Parse(idParser *src, bool rebuild=true)
Definition: Window.cpp:2130
bool GetGridVisible(void)
Definition: GEOptions.h:223
void HideWindow(idWindow *window)
float x
Definition: Vector.h:54
int MessageBox(const char *text, int flags)
Definition: GEApp.cpp:1380
void UpdateRectangle(bool useScroll=true)
void glLoadIdentity(void)
Definition: stub_gl.cpp:201
HCURSOR mHandCursor
Definition: GEWorkspace.h:260
bool GetIgnoreDesktopSelect(void)
Definition: GEOptions.h:283
GLenum GLsizei width
Definition: glext.h:2846
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void)
idList< idWindow * > mSelectMenu
Definition: GEWorkspace.h:244
idVec2 mSelectMenuPos
Definition: GEWorkspace.h:245
idWindow * GetDesktop() const
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void SetWorkspace(rvGEWorkspace *workspace)
Definition: GEProperties.h:71
idWindow * NewWindow(idDict *state, rvGEWindowWrapper::EWindowType type)
#define IDR_GUIED_ITEM_POPUP
GLenum GLsizei GLsizei height
Definition: glext.h:2856
float x
Definition: Rectangle.h:36
idRectangle & GetRect(void)
GLubyte GLubyte b
Definition: glext.h:4662
bool SetupPixelFormat(void)
#define IDC_GUIED_HAND
int GetGridWidth(void)
Definition: GEOptions.h:213
prefInfo window
void UnhideWindow(idWindow *window)
void MakeSelectedAChild(void)
viewDef_t * viewDef
Definition: tr_local.h:786
void BringSelectedToFront(void)
idVec4 & GetGridColor(void)
Definition: GEOptions.h:208
long LONG
int Append(const type &obj)
Definition: List.h:646
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
rvGENavigator & GetNavigator(void)
Definition: GEApp.h:148
static rvGEWindowWrapper * GetWrapper(idWindow *window)
idWindow * GetWindow(void)
bool Append(rvGEModifier *modifier)
const int SCREEN_WIDTH
Definition: RenderSystem.h:153
rvGESelectionMgr mSelections
Definition: GEWorkspace.h:232
void AddModifierSize(const char *modName, float l, float t, float r, float b, bool snap)
idVec2 & WorkspaceToWindow(idVec2 &point)
void AddModifierMoveNudge(float x, float y, bool snap)
Definition: GEWorkspace.h:303
void Copy(void)
tuple f
Definition: idal.py:89
EZoomLevel ZoomOut(void)
void AlignSelected(EItemAlign align)
idVec2 & WindowToWorkspace(idVec2 &point)
int Num(void) const
Definition: List.h:265
void Detach(void)
void UnhideSelected(void)
MFnDagNode * GetParent(MFnDagNode *joint)
Definition: maya_main.cpp:350
bool Contains(float xt, float yt)
Definition: Rectangle.h:48
idScreenRect scissor
Definition: tr_local.h:400
#define qglClear
Definition: qgl_linked.h:39
void HideSelected(void)
#define qglColor4f
Definition: qgl_linked.h:66
Definition: Str.h:116
idVec2 mDragPoint
Definition: GEWorkspace.h:235
PIXELFORMATDESCRIPTOR pfd
Definition: win_local.h:123
int HandleMButtonUp(WPARAM wParam, LPARAM lParam)
#define qglVertex2f
Definition: qgl_linked.h:341
rvGEStatusBar & GetStatusBar(void)
Definition: GEApp.h:173
bool IsExpression(void)
float w
Definition: Rectangle.h:38
void MakeSelectedSameSize(bool width, bool height)
#define qglBlendFunc
Definition: qgl_linked.h:36
const char * c_str(void) const
Definition: Str.h:487
#define FALSE
Definition: mprintf.c:70
#define qglFinish
Definition: qgl_linked.h:118
void UpdateCursor(void)
idRenderSystemLocal tr
void AddModifierMove(const char *modName, float x, float y, bool snap)
void BlockNextMerge(void)
#define GL_TEXTURE_CUBE_MAP_EXT
Definition: glext.h:1723
void GL_State(int stateBits)
Definition: tr_backend.cpp:239
float h
Definition: Rectangle.h:39
static bool BuildSelectMenuEnumProc(rvGEWindowWrapper *wrapper, void *data)
void Set(const float x, const float y)
Definition: Vector.h:114
#define TRUE
Definition: mprintf.c:69
short y1
Definition: tr_local.h:55
static idList< rvGEClipboardItem * > mClipboard
Definition: GEWorkspace.h:243
char * va(const char *fmt,...)
Definition: Str.cpp:1568
Win32Vars_t win32
Definition: win_main.cpp:65
short y2
Definition: tr_local.h:55
void glMatrixMode(GLenum mode)
Definition: stub_gl.cpp:218
void Refresh(void)
bool EditSelectedProperties(void)
int HandleMButtonDown(WPARAM wParam, LPARAM lParam)
int HandleLButtonUp(WPARAM wParam, LPARAM lParam)
bool EnumChildren(PFNENUMCHILDRENPROC proc, void *data)
int HandleRButtonDown(WPARAM wParam, LPARAM lParam)
idWindow * AddWindow(rvGEWindowWrapper::EWindowType type)
bool isEditor
Definition: tr_local.h:393
idWindow * GetParent()
Definition: Window.h:224
rvGEApp * mApplication
Definition: GEWorkspace.h:241
idUserInterfaceLocal * mInterface
Definition: GEWorkspace.h:217
int HandleKeyDown(WPARAM wParam, LPARAM lParam)
GLdouble GLdouble t
Definition: glext.h:2943
void Clear(void)
Definition: List.h:184