OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4MouseControl.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Mouse input */
19 
20 #include "C4Include.h"
21 #include "gui/C4MouseControl.h"
22 
23 #include "game/C4Viewport.h"
24 #include "object/C4Def.h"
25 #include "object/C4Object.h"
26 #include "game/C4Application.h"
27 #include "game/C4FullScreen.h"
28 #include "gui/C4Gui.h"
29 #include "landscape/C4Landscape.h"
30 #include "game/C4Game.h"
31 #include "player/C4Player.h"
32 #include "gui/C4ChatDlg.h"
34 #include "graphics/C4Draw.h"
35 #include "player/C4PlayerList.h"
36 #include "control/C4GameControl.h"
37 #include "gui/C4ScriptGuiWindow.h"
38 #include "lib/StdMesh.h"
39 
40 const int32_t C4MC_Drag_None = 0,
43 
44 const int32_t C4MC_Tooltip_Delay = 20;
45 
47 {
48  Default();
49 }
50 
52 {
53  Clear();
54 }
55 
57 {
58  Active=false;
60  pPlayer=nullptr;
61  Viewport=nullptr;
62  Cursor=0;
63  Caption.Clear();
65  VpX=VpY=0;
66  DownX=DownY=0;
67  ViewX=ViewY=0;
68  GuiX=GuiY=GameX=GameY=0;
70  LeftDoubleIgnoreUp=false;
72  Visible=true;
73  InitCentered=false;
74  FogOfWar=false;
76  DragObject=nullptr;
77  KeepCaption=0;
80  TargetObject=DownTarget=nullptr;
81  ControlDown=false;
82  ShiftDown=false;
83  AltDown=false;
84  Scrolling=false;
85  ScrollSpeed=10;
86  DragImageDef=nullptr;
87  DragImageObject=nullptr;
88  fMouseOwned = true; // default mouse owned
90 }
91 
93 {
94  Active = false;
95  Selection.Clear();
96  UpdateClip(); // reset mouse clipping!
97 }
98 
100 {
101 
102  if (!Active || !fMouseOwned) return;
103 
104  // Scrolling/continuous update
105  if (Scrolling || !::Game.iTick5)
106  {
107  WORD wKeyState=0;
108  if (ControlDown) wKeyState|=MK_CONTROL;
109  if (ShiftDown) wKeyState|=MK_SHIFT;
110  Move(C4MC_Button_None, VpX, VpY, wKeyState);
111  }
112 }
113 
114 bool C4MouseControl::Init(int32_t iPlayer)
115 {
116  Clear();
117  Default();
118  Active = true;
119  Player = iPlayer;
120  InitCentered = false;
121  UpdateClip();
122  return true;
123 }
124 
126 {
127  if (TargetObject==pObj) TargetObject=nullptr;
128  if (DownTarget==pObj) DownTarget=nullptr;
129  if (DragObject==pObj)
130  {
131  DragObject=nullptr;
133  DragImageDef=nullptr;
134  DragImageObject=nullptr;
135  }
136  Selection.ClearPointers(pObj);
137 }
138 
140 {
141  return (Viewport==pViewport);
142 }
143 
145 {
146 #ifdef _DEBUG
147  // never in debug
148  return;
149 #endif
150 #ifdef USE_WIN32_WINDOWS
151  // fullscreen only
152  if (Application.isEditor) return;
153  // application or mouse control not active? remove any clips
154  if (!Active || !Application.Active || ::pGUI->HasMouseFocus()) { ClipCursor(nullptr); return; }
155  // get controlled viewport
157  if (!pVP) { ClipCursor(nullptr); return; }
158  // adjust size by viewport size
159  RECT vpRct;
160  vpRct.left=pVP->OutX; vpRct.top=pVP->OutY; vpRct.right=pVP->OutX+pVP->ViewWdt; vpRct.bottom=pVP->OutY+pVP->ViewHgt;
161  // adjust by window pos
162  RECT rtWindow;
163  if (GetWindowRect(FullScreen.hWindow, &rtWindow))
164  {
165  vpRct.left += rtWindow.left; vpRct.top += rtWindow.top;
166  vpRct.right += rtWindow.left; vpRct.bottom+= rtWindow.top;
167  }
168  ClipCursor(&vpRct);
169  // and inform GUI
170  ::pGUI->SetPreferredDlgRect(C4Rect(pVP->OutX, pVP->OutY, pVP->ViewWdt, pVP->ViewHgt));
171 #endif
172  //StdWindow manages this.
173 }
174 
175 void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFlags, bool fCenter)
176 {
177  // Control state
178  ControlDown=false; if (dwKeyFlags & MK_CONTROL) ControlDown=true;
179  ShiftDown=false; if (dwKeyFlags & MK_SHIFT) ShiftDown=true;
180  AltDown=false; if(dwKeyFlags & MK_ALT) AltDown=true;
181  // Active
182  if (!Active || !fMouseOwned) return;
183  // Execute caption
184  if (KeepCaption) KeepCaption--; else { Caption.Clear(); CaptionBottomY=0; }
185  // Check player
186  if (Player>NO_OWNER)
187  {
189  if (!pPlayer) { Active=false; return; }
190  }
191  else
192  pPlayer = nullptr;
193  // Check viewport
194  if (!(Viewport=::Viewports.GetViewport(Player))) return;
195  // get view position
196  C4Rect rcViewport = Viewport->GetOutputRect();
197  fctViewport.Set(nullptr, rcViewport.x, rcViewport.y, rcViewport.Wdt, rcViewport.Hgt);
201  // First time viewport attachment: center mouse
202 #ifdef USE_WIN32_WINDOWS
203  if (!InitCentered || fCenter)
204  {
205  iX = Viewport->ViewWdt/2;
206  iY = Viewport->ViewHgt/2;
207  if (!Application.isEditor)
208  {
209  int32_t iMidX = Viewport->OutX + iX;
210  int32_t iMidY = Viewport->OutY + iY;
211  RECT rtWindow;
212  if (GetWindowRect(Application.pWindow->hWindow, &rtWindow))
213  {
214  iMidX += rtWindow.left; iMidY += rtWindow.top;
215  }
216  SetCursorPos(iMidX, iMidY);
217  }
218  InitCentered = true;
219  }
220 #else
221  if (!InitCentered || fCenter)
222  {
223  iX = Viewport->ViewWdt/2;
224  iY = Viewport->ViewHgt/2;
225  InitCentered = true;
226  }
227 #endif
228  // passive mode: scrolling and player buttons only
229  if (IsPassive())
230  {
231  if (iButton != C4MC_Button_Wheel)
232  {
233  VpX=iX; VpY=iY;
235  GuiX=float(VpX)/Viewport->GetGUIZoom(); GuiY=float(VpY)/Viewport->GetGUIZoom();
236  }
237  UpdateScrolling();
238  if (iButton == C4MC_Button_LeftDown) LeftDown();
239  else if (iButton == C4MC_Button_LeftUp) LeftUp();
240  else UpdateCursorTarget();
241  return;
242  }
243 
244  if (iButton != C4MC_Button_Wheel)
245  {
246  // Position
247  VpX=iX; VpY=iY;
249  GuiX=float(VpX)/Viewport->GetGUIZoom(); GuiY=float(VpY)/Viewport->GetGUIZoom();
250  // Scrolling
251  UpdateScrolling();
252  // Fog of war
253  UpdateFogOfWar();
254 
255  // Blocked by fog of war: evaluate button up, dragging and region controls only
256  if (FogOfWar && Drag == C4MC_Drag_None)
257  {
258  // Left button up
259  if (iButton==C4MC_Button_LeftUp)
260  {
261  LeftButtonDown=false;
262  // End any drag
264  }
265  // Right button up
266  if (iButton==C4MC_Button_RightUp)
267  {
268  RightButtonDown=false;
269  }
270  }
271  }
272 
273  // Move execution by button/drag status
274  switch (iButton)
275  {
276  //------------------------------------------------------------------------------------------
277  case C4MC_Button_None:
278  switch (Drag)
279  {
280  case C4MC_Drag_Unhandled: break; // nothing to do
281  case C4MC_Drag_None: DragNone(); break;
282  case C4MC_Drag_Script: DragScript(); break;
283  }
284  break;
285  //------------------------------------------------------------------------------------------
286  case C4MC_Button_LeftDown: LeftDown(); break;
287  //------------------------------------------------------------------------------------------
288  case C4MC_Button_LeftUp: LeftUp(); break;
289  //------------------------------------------------------------------------------------------
290  case C4MC_Button_LeftDouble: LeftDouble(); break;
291  //------------------------------------------------------------------------------------------
292  case C4MC_Button_RightDown: RightDown(); break;
293  //------------------------------------------------------------------------------------------
294  case C4MC_Button_RightUp: RightUp(); break;
295  //------------------------------------------------------------------------------------------
296  case C4MC_Button_Wheel: Wheel(dwKeyFlags); break;
297  }
298 
299  // are custom menus active?
300  bool menuProcessed = false;
301  if (pPlayer)
302  // adjust by viewport X/Y because the GUI windows calculate their positions (and thus check input) based on that
303  menuProcessed = ::Game.ScriptGuiRoot->MouseInput(iButton, iX, iY, dwKeyFlags);
304 
305  if (menuProcessed)
307 
308  // if not caught by a menu
309  if (!menuProcessed)
310  // script handling of mouse control for everything but regular movement (which is sent at control frame intervals only)
311  if (iButton != C4MC_Button_None)
312  // not if blocked by selection object
313  if (!TargetObject)
314  // safety (can't really happen in !IsPassive, but w/e
315  if (pPlayer && pPlayer->ControlSet)
316  {
317  if (!menuProcessed && pPlayer->ControlSet->IsMouseControlAssigned(iButton))
318  {
319  int wheel_dir = 0;
320  if (iButton == C4MC_Button_Wheel) wheel_dir = (short)(dwKeyFlags >> 16);
321  pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, iButton, GameX, GameY, GuiX, GuiY, (dwKeyFlags & MK_CONTROL) != 0, (dwKeyFlags & MK_SHIFT) != 0, (dwKeyFlags & MK_ALT) != 0, wheel_dir);
322  }
323  }
324 }
325 
327 {
328  // current mouse move to input queue
329  // do sanity checks
330  if (!Active || !fMouseOwned) return;
331  if (!(pPlayer=::Players.Get(Player))) return;
332  if (!pPlayer->ControlSet) return;
334  pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, C4MC_Button_None, GameX, GameY, GuiX, GuiY, ControlDown, ShiftDown, AltDown, 0);
335 }
336 
337 void C4MouseControl::Draw(C4TargetFacet &cgo, const ZoomData &GameZoom)
338 {
339  int32_t iOffsetX,iOffsetY;
340  float wdt = GfxR->fctMouseCursor.Wdt, hgt = GfxR->fctMouseCursor.Hgt;
341  // Cursor size relative to height - does not matter with current square graphics.
342  float zoom = Config.Graphics.MouseCursorSize / hgt;
343  hgt *= zoom;
344  wdt *= zoom;
345 
346  ZoomData GuiZoom;
347  pDraw->GetZoom(&GuiZoom);
348 
349  // Hidden
350  if (!Visible || !fMouseOwned) return;
351 
352  // Draw selection
353  if (!IsPassive())
354  {
356  }
357 
358  // Draw control
359  switch (Drag)
360  {
361  //------------------------------------------------------------------------------------------
363  // Hotspot offset: Usually, hotspot is in center
364  iOffsetX = wdt/2;
365  iOffsetY = hgt/2;
366  // calculate the hotspot for the scrolling cursors
367  switch (Cursor)
368  {
369  case C4MC_Cursor_Up: iOffsetY += -hgt/2; break;
370  case C4MC_Cursor_Down:iOffsetY += +hgt/2; break;
371  case C4MC_Cursor_Left: iOffsetX += -wdt/2; break;
372  case C4MC_Cursor_Right: iOffsetX += +wdt/2; break;
373  case C4MC_Cursor_UpLeft: iOffsetX += -wdt/2; iOffsetY += -hgt/2; break;
374  case C4MC_Cursor_UpRight: iOffsetX += +wdt/2; iOffsetY += -hgt/2; break;
375  case C4MC_Cursor_DownLeft: iOffsetX += -wdt/2; iOffsetY += +hgt/2; break;
376  case C4MC_Cursor_DownRight: iOffsetX += +wdt/2; iOffsetY += +hgt/2; break;
377  }
378  // Drag image
380  {
381  C4DefGraphics* pGfx;
382  if(DragImageObject)
383  pGfx = DragImageObject->GetGraphics();
384  else
385  pGfx = &DragImageDef->Graphics;
386 
387  // Determine image boundaries
388  float ImageWdt;
389  float ImageHgt;
390  if (pGfx->Type == C4DefGraphics::TYPE_Bitmap)
391  {
393  ImageWdt = Def->PictureRect.Wdt;
394  ImageHgt = Def->PictureRect.Hgt;
395  }
396  else if (pGfx->Type == C4DefGraphics::TYPE_Mesh)
397  {
398  // Note bounding box is in OGRE coordinate system
399  ImageWdt = pGfx->Mesh->GetBoundingBox().y2 - pGfx->Mesh->GetBoundingBox().y1;
400  ImageHgt = pGfx->Mesh->GetBoundingBox().z2 - pGfx->Mesh->GetBoundingBox().z1;
401  }
402  else
403  {
404  ImageWdt = ImageHgt = 1.0f;
405  }
406 
407  // zoom mode: Drag in GUI or Game depending on source object
408  bool fIsGameZoom = true;
410  fIsGameZoom = false;
411  // drag image in game zoom
412  float XDraw, YDraw, ZoomDraw;
413  if (fIsGameZoom)
414  {
415  pDraw->SetZoom(GameZoom);
416  XDraw = GameX; YDraw = GameY;
417  ZoomDraw = 1.0f;
418  }
419  else
420  {
421  ZoomDraw = std::min(64.0f / ImageWdt, 64.0f / ImageHgt);
422  XDraw = GuiX; YDraw = GuiY;
423  }
424 
425  iOffsetX=int(ZoomDraw*ImageWdt/2);
426  iOffsetY=int(ZoomDraw*ImageHgt/2);
427 
428  C4TargetFacet ccgo;
429  ccgo.Set(cgo.Surface, XDraw + cgo.X - iOffsetX, YDraw + cgo.Y - iOffsetY, float(ImageWdt)*ZoomDraw, float(ImageHgt)*ZoomDraw);
430 
431  if (DragImageObject)
432  {
433  uint32_t ColorMod = DragImageObject->ColorMod;
434  uint32_t BlitMode = DragImageObject->BlitMode;
435  DragImageObject->ColorMod = (Drag == C4MC_Drag_Script) ? 0x7fffffff : (/*DragImagePhase*/0 ? 0x8f7f0000 : 0x1f007f00);
437 
438  DragImageObject->DrawPicture(ccgo, false, nullptr);
439 
440  DragImageObject->ColorMod = ColorMod;
441  DragImageObject->BlitMode = BlitMode;
442  }
443  else
444  {
445  // draw in special modulation mode
447  // draw DragImage in red or green, according to the phase to be used
448  pDraw->ActivateBlitModulation((Drag == C4MC_Drag_Script) ? 0x7fffffff : (/*DragImagePhase*/0 ? 0x8f7f0000 : 0x1f007f00));
449 
450  DragImageDef->Draw(ccgo, false, pPlayer ? pPlayer->ColorDw : 0xff0000ff, nullptr, 0, 0, nullptr);
451 
452  // reset color
454  pDraw->SetBlitMode(0);
455  }
456 
457  if (fIsGameZoom) pDraw->SetZoom(GuiZoom);
458  // reset cursor hotspot offset for script drawing
459  iOffsetX = wdt/2;
460  iOffsetY = hgt/2;
461  }
462  // Cursor
464  {
465  GfxR->fctMouseCursor.DrawX(cgo.Surface, cgo.X+GuiX-iOffsetX, cgo.Y+GuiY-iOffsetY, wdt, hgt, Cursor);
466  }
467  break;
468  //------------------------------------------------------------------------------------------
469  }
470 
471  // Draw caption
472  if (Caption && ::pGUI)
473  {
474  C4TargetFacet cgoTip;
475  cgoTip = static_cast<const C4Facet &>(cgo);
476  C4GUI::Screen::DrawToolTip(Caption.getData(), cgoTip, cgo.X+GuiX, cgo.Y+GuiY);
477  }
478 
479 }
480 
482 {
483  C4Object* OldTargetObject = TargetObject;
484 
485  if (Scrolling)
486  {
487  // Scrolling: no other target
488  TargetObject=nullptr;
489  }
490  else
491  {
492  // Target object
495 
496  // Movement
498 
499  // Target action
500  if (TargetObject && !IsPassive())
501  {
502  // default cursor for object; also set if not in FoW
504 
505  // select custom region. Can select an object if it does not have the MD_NoClick
506  // flag set. If we are currently dragging then selection depends on it being a drop target.
507  bool CanSelect;
508  if(Drag == C4MC_Drag_Script)
510  else
512 
513  if ( (TargetObject->Category & C4D_MouseSelect) && CanSelect)
515  else
516  TargetObject = nullptr;
517  }
518 
519  // passive cursor
520  if (IsPassive())
522 
523  // update tooltip information
524  if (OldTargetObject != TargetObject)
525  {
526  C4String *newTooltip = nullptr;
528  {
529  float objX, objY;
531  objX += TargetObject->Shape.x;
532  objY += TargetObject->Shape.y - TargetObject->addtop();
534  SetTooltipText(StdStrBuf(newTooltip->GetCStr()));
535  }
536  else
537  {
538  SetTooltipRectangle(C4Rect(0, 0, 0, 0));
539  }
540  }
541 
542  if (!KeepCaption
543  && ToolTipRectangle.Wdt != 0
546  {
548 
550  {
552  }
553  }
554  else
555  {
556  // disable tooltip pop-up; whatever set it in the first place will set it again on the next mouse-enter
558  ToolTipRectangle.Wdt = 0;
559  }
560  }
561 
562  // Make a script callback if the object being hovered changes
563  if(!IsPassive() && OldTargetObject != TargetObject)
564  {
565  // TODO: This might put a heavy load on the network, depending on the number of
566  // selectable objects around. If it turns out to be a problem we might want to
567  // deduce these hover callbacks client-side instead.
568  // Or, make sure to send this at most once per control frame.
570  }
571 }
572 
574 {
575  // Set single selection if cursor on selection object (clear prior object selection)
578 
579  // Cursor has moved off single object (or target object) selection: clear selection
580  else if (Selection.GetObject())
583  Selection.Clear();
584 
585  return Selection.ObjectCount();
586 }
587 
589 {
590  // Assume no scrolling
591  Scrolling=false;
592  // No scrolling if disabled by player
593  if (pPlayer) if (pPlayer->IsViewLocked()) return;
594  // Scrolling on border
595  if (VpX==0)
597  if (VpY==0)
599  if (VpX==Viewport->ViewWdt-1)
601  if (VpY==Viewport->ViewHgt-1)
603  // Set correct cursor
604  if ((VpX==0) && (VpY==0)) Cursor=C4MC_Cursor_UpLeft;
605  if ((VpX==Viewport->ViewWdt-1) && (VpY==0)) Cursor=C4MC_Cursor_UpRight;
606  if ((VpX==0) && (VpY==Viewport->ViewHgt-1)) Cursor=C4MC_Cursor_DownLeft;
608 }
609 
611 {
612  // Set flag
613  LeftButtonDown=true;
614  // Store down values (same MoveRightDown -> use StoreDown)
617 }
618 
620 {
621  // Ignore left up after double click
622  if (LeftDoubleIgnoreUp)
623  {
624  LeftDoubleIgnoreUp=false;
625  }
626  else
627  {
628  // Evaluate by drag status
629  switch (Drag)
630  {
631  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
632  case C4MC_Drag_Unhandled: // nobreak
633  case C4MC_Drag_None: LeftUpDragNone(); break;
634  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
635  case C4MC_Drag_Script: ButtonUpDragScript(); break;
636  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
637  }
638  }
639  // Update status flag
640  LeftButtonDown=false;
641  if(!RightButtonDown) DownTarget = nullptr;
642 }
643 
645 {
646  // Cursor movement
648  // Update selection
650 
651  // Button down: begin drag
654  {
655  bool fAllowDrag = true;
656  // check if target object allows scripted dragging
657  if (fAllowDrag && DownTarget && (!FogOfWar || (DownTarget->Category & C4D_IgnoreFoW)))
658  {
659  C4Object *drag_image_obj; C4Def * drag_image_def;
660 
661  // Drag only if MD_SOURCE is set and drag image is present
663  DownTarget->GetDragImage(&drag_image_obj, &drag_image_def))
664  {
666 
667  if(drag_image_obj) DragImageObject = drag_image_obj;
668  else DragImageDef = drag_image_def;
669 
671  }
672  }
673 
674  // dragging somewhere unhandled - mark drag process so moving over a draggable object won't start a drag
675  if (Drag == C4MC_Drag_None)
676  {
678  }
679  }
680 }
681 
683 {
684  // Update status flag
685  LeftButtonDown=false;
686  // Set ignore flag for next left up
687  LeftDoubleIgnoreUp=true;
688  // Evaluate left double by drag status (can only be C4MC_Drag_None really)
689  switch (Drag)
690  {
691  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
692  case C4MC_Drag_None:
693  // Double left click (might be on a target)
694  break;
695  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
696  }
697 }
698 
700 {
701  // Update status flag
702  RightButtonDown=true;
703  // Store down values (same MoveLeftDown -> use StoreDown)
706 }
707 
709 {
710  // Evaluate by drag status
711  switch (Drag)
712  {
713  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
714  case C4MC_Drag_Unhandled: // nobreak
715  case C4MC_Drag_None: RightUpDragNone(); break;
716  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
717  case C4MC_Drag_Script: ButtonUpDragScript(); break;
718  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
719  }
720  // Update status flag
721  RightButtonDown=false;
722  if(!LeftButtonDown) DownTarget = nullptr;
723 }
724 
726 {
727 }
728 
730 {
731  // script drag should update target and selection so selection highlight on drop target is visible
732  // Cursor movement
734  // Update selection
737 }
738 
740 {
741  // might be in Drag_Unknown
743  // Single left click (might be on a target)
744  switch (Cursor)
745  {
746  case C4MC_Cursor_Select:
747  // Object selection to control queue
748  if (!IsPassive() && Selection.GetObject() == DownTarget)
750  break;
751  default:
752  // done in script
753  break;
754  }
755  // Clear selection
756  Selection.Clear();
757 }
758 
760 {
761  // Determine drag+drop targets
763  // Finish drag
766  DragImageObject = nullptr;
767  DragImageDef = nullptr;
768  C4Object *DragObject = this->DragObject;
769  this->DragObject = nullptr;
770  C4Object *DropObject = TargetObject;
771  // drag object must exist; drop object is optional
772  if (!DragObject) return;
773  if (DropObject && (~DropObject->GetPropertyInt(P_MouseDrag) & C4MC_MD_DropTarget))
774  DropObject = nullptr;
775  // no commands if player is eliminated or doesn't exist any more
776  C4Player *pPlr = ::Players.Get(Player);
777  if (!pPlr || pPlr->Eliminated) return;
778  // todo: Perform drag/drop validity check
779  // now drag/drop is handled by script
781 }
782 
784 {
785 
786  // might be in Drag_Unknown
788 
789  // Alternative object selection
792 
793  // TODO: Evaluate right click
794 
795 }
796 
798 {
799  // Assume no fog of war
800  FogOfWar=false;
801  // Check for fog of war
802  // TODO: Check C4FoWRegion... should maybe be passed as a parameter?
803  // pDraw->GetFoW() might not be current at this time.
804  if (/*(pPlayer->fFogOfWar && !pPlayer->FoWIsVisible(int32_t(GameX),int32_t(GameY))) || */GameX<0 || GameY<0 || int32_t(GameX)>=::Landscape.GetWidth() || int32_t(GameY)>=::Landscape.GetHeight())
805  {
806  FogOfWar=true;
807  // allow dragging, scrolling, region selection and manipulations of objects not affected by FoW
809  {
811  }
812  }
813 }
814 
816 {
817  Visible=true;
818 }
819 
821 {
822  Visible=false;
823 }
824 
826 {
827  return Caption.getData();
828 }
829 
831 {
832  // Set the tooltip rectangle slightly larger than originally requested.
833  // The tooltip will be removed when the cursor leaves the rectangle, so make sure that the tooltip is not already disabled when the cursor moves to the border-pixel of the GUI item
834  // in case the GUI item uses a different check for bounds (< vs <=) than the tooltip rectangle.
835  ToolTipRectangle = C4Rect(rectangle.x - 2, rectangle.y - 2, rectangle.Wdt + 4, rectangle.Hgt + 4);
837 }
838 
840 {
841  TooltipText = text;
842 }
843 
845 {
846  // find object
847  // gui object position currently wrong...will fall apart once GUIZoom is activated
849  if (!pObj) return nullptr;
850  return pObj;
851 }
852 
854 {
856 }
857 
858 void C4MouseControl::ScrollView(float iX, float iY, float ViewWdt, float ViewHgt)
859 {
860  // player assigned: scroll player view
861  if (pPlayer)
862  pPlayer->ScrollView(iX, iY, ViewWdt, ViewHgt);
863  else if (Viewport)
864  {
865  // no player: Scroll fullscreen viewport
866  Viewport->ScrollView(iX, iY);
867  }
868 
869 }
870 
872 {
873  return Active && Drag == C4MC_Drag_Script;
874 }
875 
876 bool C4MouseControl::GetLastCursorPos(int32_t *x_out_gui, int32_t *y_out_gui, int32_t *x_out_game, int32_t *y_out_game) const
877 {
878  // safety
879  if (!Active || !fMouseOwned) return false;
880  // OK; assign last known pos
881  *x_out_gui = GuiX; *y_out_gui = GuiY;
882  *x_out_game = GameX; *y_out_game = GameY;
883  return true;
884 }
const char * getData() const
Definition: StdBuf.h:450
void SetTooltipRectangle(const C4Rect &rectangle)
int32_t OutX
Definition: C4Viewport.h:107
C4ObjectList Selection
C4Config Config
Definition: C4Config.cpp:837
const int32_t C4MC_Button_LeftDown
int32_t OutY
Definition: C4Viewport.h:107
float Y
Definition: C4Facet.h:120
C4Rect ToolTipRectangle
#define C4GFXBLIT_MOD2
Definition: C4Surface.h:29
#define GfxR
virtual bool Add(C4Object *nObj, SortType eSort, C4ObjectList *pLstSorted=nullptr)
C4Player * pPlayer
int32_t iTick5
Definition: C4Game.h:131
const int32_t C4MC_Drag_Script
C4Game Game
Definition: C4Globals.cpp:52
int32_t TimeInTooltipRectangle
void GetViewPos(float &riX, float &riY, float tx, float ty, const C4Facet &fctViewport) const
Definition: C4Object.cpp:4332
C4Rect PictureRect
Definition: C4Def.h:109
const int32_t C4MC_Cursor_Right
void Clear()
Definition: StdBuf.h:474
bool GetDragImage(C4Object **drag_object, C4Def **drag_id) const
Definition: C4Object.cpp:4290
void DrawPicture(C4Facet &cgo, bool fSelected=false, C4DrawTransform *transform=nullptr)
Definition: C4Object.cpp:2343
const int32_t C4MC_Cursor_Passive
StdCopyStrBuf TooltipText
const int32_t C4MC_Cursor_DragDrop
C4Object * DragImageObject
const char * GetCStr() const
Definition: C4StringTable.h:49
int32_t UpdateSingleSelection()
void Add(C4PacketType eType, C4ControlPacket *pCtrl)
Definition: C4Control.h:82
const int32_t C4MC_DragSensitivity
C4FullScreen FullScreen
Definition: C4Globals.cpp:46
const int32_t C4MC_Button_RightUp
Definition: C4Rect.h:29
C4Object * DownTarget
int32_t MouseCursorSize
Definition: C4Config.h:119
bool ButtonDownOnSelection
C4Viewport * GetViewport(int32_t iPlayer, C4Viewport *pPrev=nullptr)
const int32_t C4MC_Cursor_Down
C4PlayerControl Control
Definition: C4Player.h:131
bool IsViewLocked() const
Definition: C4Player.h:206
void SetPreferredDlgRect(const C4Rect &rtNewPref)
Definition: C4Gui.h:2648
C4Object * TargetObject
bool GetLastCursorPos(int32_t *x_out_gui, int32_t *y_out_gui, int32_t *x_out_game, int32_t *y_out_game) const
void Set(C4Surface &rSfc)
Definition: C4Facet.cpp:459
static void DrawToolTip(const char *szTip, C4TargetFacet &cgo, float guix, float guiy)
Definition: C4Gui.cpp:1012
void ScrollView(float iX, float iY, float ViewWdt, float ViewHgt)
C4TargetFacet last_gui_draw_cgo
Definition: C4Viewport.h:41
const int32_t C4MC_MD_NoClick
void SetBlitMode(DWORD dwBlitMode)
Definition: C4Draw.h:191
const int32_t C4MC_MD_DropTarget
C4Facet fctViewportGame
const int32_t C4MC_Button_LeftDouble
uint32_t ColorDw
Definition: C4Player.h:91
int32_t ViewHgt
Definition: C4Viewport.h:36
C4ConfigGraphics Graphics
Definition: C4Config.h:254
int32_t Wdt
Definition: C4Rect.h:32
bool DoMouseInput(uint8_t mouse_id, int32_t mouseevent, float game_x, float game_y, float gui_x, float gui_y, bool is_ctrl_down, bool is_shift_down, bool is_alt_down, int wheel_dir)
const int32_t C4D_IgnoreFoW
Definition: C4Def.h:57
void SetTooltipText(const StdStrBuf &text)
const int32_t C4D_MouseSelect
Definition: C4Def.h:54
void Draw(C4TargetFacet &cgo, const ZoomData &GameZoom)
C4Player * Get(int iPlayer) const
const int32_t C4MC_Drag_None
C4GUIScreen * pGUI
Definition: C4Gui.cpp:1194
class C4PlayerControlAssignmentSet * ControlSet
Definition: C4Player.h:92
const int32_t C4MC_Button_LeftUp
C4Def * Def
Definition: C4Object.h:143
bool Active
Definition: C4App.h:63
int32_t ViewWdt
Definition: C4Viewport.h:36
void ScrollView(float iX, float iY, float ViewWdt, float ViewHgt)
Definition: C4Player.cpp:1366
int32_t y
Definition: C4Rect.h:32
bool IsViewport(C4Viewport *pViewport)
void Default()
Definition: C4Facet.cpp:31
C4GameControl Control
void Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFlags, bool fCenter=false)
C4Landscape Landscape
StdCopyStrBuf Caption
const int32_t C4MC_Cursor_Left
C4DefGraphics * GetGraphics() const
Definition: C4Object.h:340
int32_t ScrollSpeed
static const C4ID None
Definition: C4Id.h:42
const int32_t C4MC_Cursor_DownLeft
void Set(const C4Facet &cpy)
Definition: C4Facet.h:184
C4Object * DragObject
void ScrollView(float byX, float byY)
Definition: C4Viewport.cpp:734
C4PlayerList Players
const int32_t C4MC_Tooltip_Delay
void Draw(C4Facet &cgo, bool fSelected=false, DWORD iColor=0, C4Object *pObj=nullptr, int32_t iPhaseX=0, int32_t iPhaseY=0, C4DrawTransform *trans=nullptr, const char *graphicsName=nullptr)
Definition: C4Def.cpp:601
Definition: C4Def.h:100
const int NO_OWNER
Definition: C4Constants.h:138
int32_t CaptionBottomY
C4Rect GetOutputRect()
Definition: C4Viewport.h:64
C4Draw * pDraw
Definition: C4Draw.cpp:45
const int32_t C4MC_Cursor_Select
C4Object * GetObject(int Index=0) const
C4Viewport * Viewport
C4Def * DragImageDef
int32_t Eliminated
Definition: C4Player.h:85
bool IsMouseControlAssigned(int32_t mouseevent) const
static C4ControlPlayerMouse * Hover(const C4Player *player, const C4Object *target, const C4Object *old_target, const C4Object *drag=nullptr)
Definition: C4Control.cpp:456
float Zoom
Definition: C4Viewport.h:101
C4Facet fctViewportGUI
const int32_t C4MC_Button_RightDown
int32_t Category
Definition: C4Object.h:113
C4Control & Input
Definition: C4Game.h:84
C4TargetFacet last_game_draw_cgo
Definition: C4Viewport.h:41
int32_t x
Definition: C4Rect.h:32
const int32_t C4MC_Cursor_Up
int32_t GetHeight() const
void Wheel(DWORD dwFlags)
const int32_t C4MC_Button_Wheel
int ObjectCount(C4ID id=C4ID::None) const
const int32_t C4MC_Drag_Unhandled
C4ViewportList Viewports
Definition: C4Viewport.cpp:841
float GetViewY()
Definition: C4Viewport.h:75
bool HasMouseFocus()
Definition: C4Gui.h:2675
uint32_t ColorMod
Definition: C4Object.h:161
void GetZoom(ZoomData *r)
Definition: C4Draw.h:197
const int32_t C4MC_Cursor_UpLeft
const int32_t C4MC_MD_DragSource
GraphicsType Type
Definition: C4DefGraphics.h:48
bool isReplay() const
Definition: C4GameControl.h:98
bool Init(int32_t iPlayer)
const int32_t C4MC_Button_None
float GetGUIZoom() const
Definition: C4Viewport.h:47
C4Facet fctViewport
void DeactivateBlitModulation()
Definition: C4Draw.h:189
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
Definition: C4PropList.cpp:863
int ClearPointers(C4Object *pObj)
virtual void Default()
void DrawSelectMark(C4TargetFacet &cgo) const
uint32_t BlitMode
Definition: C4Object.h:162
const int32_t C4MC_Cursor_DownRight
void ActivateBlitModulation(DWORD dwWithClr)
Definition: C4Draw.h:188
int32_t Hgt
Definition: C4Rect.h:32
T Abs(T val)
Definition: Standard.h:44
virtual void Clear()
std::unique_ptr< C4ScriptGuiWindow > ScriptGuiRoot
Definition: C4Game.h:235
C4Shape Shape
Definition: C4Object.h:148
const int32_t C4MC_Cursor_UpRight
C4Surface * Surface
Definition: C4Facet.h:119
C4Object * FindVisObject(float tx, float ty, int32_t iPlr, const C4Facet &fctViewportGame, const C4Facet &fctViewportGUI, float iX, float iY, DWORD category, float gui_x, float gui_y)
Definition: C4Game.cpp:1229
static C4ControlPlayerMouse * DragDrop(const C4Player *player, const C4Object *target, const C4Object *drag)
Definition: C4Control.cpp:469
C4Object * GetTargetObject()
uint32_t DWORD
float GetViewX()
Definition: C4Viewport.h:73
bool ObjectInCrew(C4Object *tobj)
Definition: C4Player.cpp:92
const char * GetCaption()
void SetZoom(float X, float Y, float Zoom)
Definition: C4Draw.cpp:782
C4String * GetPropertyStr(C4PropertyName k) const
Definition: C4PropList.cpp:752
void ClearPointers(C4Object *pObj)
C4DefGraphics Graphics
Definition: C4Def.h:194
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:45
float X
Definition: C4Facet.h:120
C4Window * pWindow
Definition: C4App.h:80
C4Application Application
Definition: C4Globals.cpp:44
const int32_t C4MC_Cursor_Crosshair
uint16_t WORD
const int32_t C4D_Foreground
Definition: C4Def.h:55
int32_t addtop() const
Definition: C4Object.h:281
int32_t GetWidth() const