2009-05-08 13:28:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2013-12-17 20:01:09 +00:00
* Copyright ( c ) 1998 - 2000 , Matthes Bender
* Copyright ( c ) 2001 - 2009 , RedWolf Design GmbH , http : //www.clonk.de/
2016-04-03 18:18:29 +00:00
* Copyright ( c ) 2009 - 2016 , The OpenClonk Team and contributors
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* Distributed under the terms of the ISC license ; see accompanying file
* " COPYING " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* " Clonk " is a registered trademark of Matthes Bender , used with permission .
* See accompanying file " TRADEMARK " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* To redistribute this file separately , substitute the full license texts
* for the above references .
2009-05-08 13:28:41 +00:00
*/
/* Mouse input */
2016-04-03 18:07:56 +00:00
# include "C4Include.h"
# include "gui/C4MouseControl.h"
2009-05-08 13:28:41 +00:00
2017-04-30 08:49:09 +00:00
# include "control/C4GameControl.h"
2016-04-03 18:07:56 +00:00
# include "game/C4Application.h"
# include "game/C4FullScreen.h"
2017-04-30 08:49:09 +00:00
# include "game/C4Viewport.h"
# include "graphics/C4Draw.h"
# include "graphics/C4GraphicsResource.h"
# include "gui/C4ChatDlg.h"
2016-04-03 18:07:56 +00:00
# include "gui/C4Gui.h"
2017-04-30 08:49:09 +00:00
# include "gui/C4ScriptGuiWindow.h"
2016-04-03 18:07:56 +00:00
# include "landscape/C4Landscape.h"
2017-04-30 08:49:09 +00:00
# include "lib/StdMesh.h"
# include "object/C4Def.h"
# include "object/C4Object.h"
2016-04-03 18:07:56 +00:00
# include "player/C4Player.h"
# include "player/C4PlayerList.h"
2009-05-08 13:28:41 +00:00
2010-04-18 08:51:50 +00:00
const int32_t C4MC_Drag_None = 0 ,
C4MC_Drag_Script = 6 ,
2012-11-16 16:29:42 +00:00
C4MC_Drag_Unhandled = 7 ;
2014-10-11 09:29:02 +00:00
const int32_t C4MC_Tooltip_Delay = 20 ;
2009-05-08 13:28:41 +00:00
C4MouseControl : : C4MouseControl ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Default ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4MouseControl : : ~ C4MouseControl ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Clear ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : Default ( )
2010-03-28 18:58:01 +00:00
{
2009-08-15 18:50:32 +00:00
Active = false ;
2009-05-08 13:28:41 +00:00
Player = NO_OWNER ;
2016-11-02 23:58:02 +00:00
pPlayer = nullptr ;
Viewport = nullptr ;
2012-11-16 16:29:42 +00:00
Cursor = 0 ;
2009-05-08 13:28:41 +00:00
Caption . Clear ( ) ;
CaptionBottomY = 0 ;
VpX = VpY = 0 ;
2012-11-16 16:29:42 +00:00
DownX = DownY = 0 ;
2009-05-08 13:28:41 +00:00
ViewX = ViewY = 0 ;
GuiX = GuiY = GameX = GameY = 0 ;
LeftButtonDown = RightButtonDown = false ;
LeftDoubleIgnoreUp = false ;
ButtonDownOnSelection = false ;
Visible = true ;
InitCentered = false ;
FogOfWar = false ;
2010-01-25 03:14:52 +00:00
DragID = C4ID : : None ;
2016-11-02 23:58:02 +00:00
DragObject = nullptr ;
2009-05-08 13:28:41 +00:00
KeepCaption = 0 ;
2012-11-16 16:29:42 +00:00
Drag = C4MC_Drag_None ;
2009-05-08 13:28:41 +00:00
Selection . Default ( ) ;
2016-11-02 23:58:02 +00:00
TargetObject = DownTarget = nullptr ;
2009-05-08 13:28:41 +00:00
ControlDown = false ;
ShiftDown = false ;
2012-04-22 20:09:06 +00:00
AltDown = false ;
2009-05-08 13:28:41 +00:00
Scrolling = false ;
ScrollSpeed = 10 ;
2016-11-02 23:58:02 +00:00
DragImageDef = nullptr ;
DragImageObject = nullptr ;
2009-08-15 18:50:32 +00:00
fMouseOwned = true ; // default mouse owned
2009-05-08 13:28:41 +00:00
fctViewport . Default ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : Clear ( )
2010-03-28 18:58:01 +00:00
{
2009-08-15 18:50:32 +00:00
Active = false ;
2009-05-08 13:28:41 +00:00
Selection . Clear ( ) ;
UpdateClip ( ) ; // reset mouse clipping!
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : Execute ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( ! Active | | ! fMouseOwned ) return ;
// Scrolling/continuous update
2009-06-12 18:52:21 +00:00
if ( Scrolling | | ! : : Game . iTick5 )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
WORD wKeyState = 0 ;
2012-04-22 20:09:06 +00:00
if ( ControlDown ) wKeyState | = MK_CONTROL ;
if ( ShiftDown ) wKeyState | = MK_SHIFT ;
2018-01-17 23:40:39 +00:00
if ( AltDown ) wKeyState | = MK_ALT ;
2012-11-16 16:29:42 +00:00
Move ( C4MC_Button_None , VpX , VpY , wKeyState ) ;
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MouseControl : : Init ( int32_t iPlayer )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Clear ( ) ;
Default ( ) ;
2009-08-15 18:50:32 +00:00
Active = true ;
2009-05-08 13:28:41 +00:00
Player = iPlayer ;
InitCentered = false ;
UpdateClip ( ) ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : ClearPointers ( C4Object * pObj )
2010-03-28 18:58:01 +00:00
{
2016-11-02 23:58:02 +00:00
if ( TargetObject = = pObj ) TargetObject = nullptr ;
if ( DownTarget = = pObj ) DownTarget = nullptr ;
2009-12-30 19:16:32 +00:00
if ( DragObject = = pObj )
{
2016-11-02 23:58:02 +00:00
DragObject = nullptr ;
2009-12-30 19:16:32 +00:00
Drag = C4MC_Drag_None ;
2016-11-02 23:58:02 +00:00
DragImageDef = nullptr ;
DragImageObject = nullptr ;
2009-12-30 19:16:32 +00:00
}
2009-05-08 13:28:41 +00:00
Selection . ClearPointers ( pObj ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MouseControl : : IsViewport ( C4Viewport * pViewport )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
return ( Viewport = = pViewport ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : UpdateClip ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
# ifdef _DEBUG
// never in debug
return ;
# endif
2012-03-23 21:53:56 +00:00
# ifdef USE_WIN32_WINDOWS
2009-05-08 13:28:41 +00:00
// fullscreen only
2010-09-28 18:16:33 +00:00
if ( Application . isEditor ) return ;
2009-05-08 13:28:41 +00:00
// application or mouse control not active? remove any clips
2016-11-02 23:58:02 +00:00
if ( ! Active | | ! Application . Active | | : : pGUI - > HasMouseFocus ( ) ) { ClipCursor ( nullptr ) ; return ; }
2009-05-08 13:28:41 +00:00
// get controlled viewport
2010-09-29 01:44:05 +00:00
C4Viewport * pVP = : : Viewports . GetViewport ( Player ) ;
2016-11-02 23:58:02 +00:00
if ( ! pVP ) { ClipCursor ( nullptr ) ; return ; }
2009-05-08 13:28:41 +00:00
// adjust size by viewport size
RECT vpRct ;
vpRct . left = pVP - > OutX ; vpRct . top = pVP - > OutY ; vpRct . right = pVP - > OutX + pVP - > ViewWdt ; vpRct . bottom = pVP - > OutY + pVP - > ViewHgt ;
// adjust by window pos
RECT rtWindow ;
if ( GetWindowRect ( FullScreen . hWindow , & rtWindow ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
vpRct . left + = rtWindow . left ; vpRct . top + = rtWindow . top ;
vpRct . right + = rtWindow . left ; vpRct . bottom + = rtWindow . top ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
ClipCursor ( & vpRct ) ;
// and inform GUI
2010-10-29 23:47:50 +00:00
: : pGUI - > SetPreferredDlgRect ( C4Rect ( pVP - > OutX , pVP - > OutY , pVP - > ViewWdt , pVP - > ViewHgt ) ) ;
2009-05-08 13:28:41 +00:00
# endif
//StdWindow manages this.
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
void C4MouseControl : : Move ( int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyFlags , bool fCenter )
2009-10-16 21:07:43 +00:00
{
2012-04-22 20:09:06 +00:00
// Control state
ControlDown = false ; if ( dwKeyFlags & MK_CONTROL ) ControlDown = true ;
ShiftDown = false ; if ( dwKeyFlags & MK_SHIFT ) ShiftDown = true ;
AltDown = false ; if ( dwKeyFlags & MK_ALT ) AltDown = true ;
2009-05-08 13:28:41 +00:00
// Active
if ( ! Active | | ! fMouseOwned ) return ;
// Execute caption
2012-04-15 10:09:54 +00:00
if ( KeepCaption ) KeepCaption - - ; else { Caption . Clear ( ) ; CaptionBottomY = 0 ; }
2009-05-08 13:28:41 +00:00
// Check player
2010-09-08 21:49:42 +00:00
if ( Player > NO_OWNER )
{
pPlayer = : : Players . Get ( Player ) ;
if ( ! pPlayer ) { Active = false ; return ; }
}
else
2016-11-02 23:58:02 +00:00
pPlayer = nullptr ;
2009-05-08 13:28:41 +00:00
// Check viewport
2010-09-29 01:44:05 +00:00
if ( ! ( Viewport = : : Viewports . GetViewport ( Player ) ) ) return ;
2009-05-08 13:28:41 +00:00
// get view position
C4Rect rcViewport = Viewport - > GetOutputRect ( ) ;
2016-11-02 23:58:02 +00:00
fctViewport . Set ( nullptr , rcViewport . x , rcViewport . y , rcViewport . Wdt , rcViewport . Hgt ) ;
2015-01-03 21:51:02 +00:00
ViewX = Viewport - > GetViewX ( ) ; ViewY = Viewport - > GetViewY ( ) ;
2009-10-16 21:07:43 +00:00
fctViewportGame = Viewport - > last_game_draw_cgo ;
fctViewportGUI = Viewport - > last_gui_draw_cgo ;
2009-05-08 13:28:41 +00:00
// First time viewport attachment: center mouse
2012-03-23 21:53:56 +00:00
# ifdef USE_WIN32_WINDOWS
2009-05-08 13:28:41 +00:00
if ( ! InitCentered | | fCenter )
{
iX = Viewport - > ViewWdt / 2 ;
iY = Viewport - > ViewHgt / 2 ;
2010-09-28 18:16:33 +00:00
if ( ! Application . isEditor )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
int32_t iMidX = Viewport - > OutX + iX ;
int32_t iMidY = Viewport - > OutY + iY ;
RECT rtWindow ;
if ( GetWindowRect ( Application . pWindow - > hWindow , & rtWindow ) )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
iMidX + = rtWindow . left ; iMidY + = rtWindow . top ;
}
2009-10-16 21:07:43 +00:00
SetCursorPos ( iMidX , iMidY ) ;
}
2009-05-08 13:28:41 +00:00
InitCentered = true ;
}
# else
if ( ! InitCentered | | fCenter )
{
iX = Viewport - > ViewWdt / 2 ;
iY = Viewport - > ViewHgt / 2 ;
InitCentered = true ;
}
# endif
// passive mode: scrolling and player buttons only
if ( IsPassive ( ) )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
if ( iButton ! = C4MC_Button_Wheel )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
VpX = iX ; VpY = iY ;
GameX = ViewX + VpX / Viewport - > Zoom ; GameY = ViewY + VpY / Viewport - > Zoom ;
2011-08-18 17:46:51 +00:00
GuiX = float ( VpX ) / Viewport - > GetGUIZoom ( ) ; GuiY = float ( VpY ) / Viewport - > GetGUIZoom ( ) ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
UpdateScrolling ( ) ;
if ( iButton = = C4MC_Button_LeftDown ) LeftDown ( ) ;
else if ( iButton = = C4MC_Button_LeftUp ) LeftUp ( ) ;
else UpdateCursorTarget ( ) ;
return ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
if ( iButton ! = C4MC_Button_Wheel )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// Position
VpX = iX ; VpY = iY ;
GameX = ViewX + VpX / Viewport - > Zoom ; GameY = ViewY + VpY / Viewport - > Zoom ;
2011-08-18 17:46:51 +00:00
GuiX = float ( VpX ) / Viewport - > GetGUIZoom ( ) ; GuiY = float ( VpY ) / Viewport - > GetGUIZoom ( ) ;
2009-05-08 13:28:41 +00:00
// Scrolling
UpdateScrolling ( ) ;
// Fog of war
UpdateFogOfWar ( ) ;
// Blocked by fog of war: evaluate button up, dragging and region controls only
2012-11-16 16:29:42 +00:00
if ( FogOfWar & & Drag = = C4MC_Drag_None )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// Left button up
if ( iButton = = C4MC_Button_LeftUp )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
LeftButtonDown = false ;
// End any drag
Drag = C4MC_Drag_None ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
// Right button up
if ( iButton = = C4MC_Button_RightUp )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
RightButtonDown = false ;
}
}
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
// Move execution by button/drag status
switch ( iButton )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2010-03-28 18:58:01 +00:00
case C4MC_Button_None :
switch ( Drag )
{
2010-04-18 08:51:50 +00:00
case C4MC_Drag_Unhandled : break ; // nothing to do
2010-03-28 18:58:01 +00:00
case C4MC_Drag_None : DragNone ( ) ; break ;
case C4MC_Drag_Script : DragScript ( ) ; break ;
}
break ;
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2010-03-28 18:58:01 +00:00
case C4MC_Button_LeftDown : LeftDown ( ) ; break ;
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2010-03-28 18:58:01 +00:00
case C4MC_Button_LeftUp : LeftUp ( ) ; break ;
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2010-03-28 18:58:01 +00:00
case C4MC_Button_LeftDouble : LeftDouble ( ) ; break ;
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2010-03-28 18:58:01 +00:00
case C4MC_Button_RightDown : RightDown ( ) ; break ;
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2010-03-28 18:58:01 +00:00
case C4MC_Button_RightUp : RightUp ( ) ; break ;
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2010-03-28 18:58:01 +00:00
case C4MC_Button_Wheel : Wheel ( dwKeyFlags ) ; break ;
2009-05-08 13:28:41 +00:00
}
2009-10-17 15:53:26 +00:00
2013-02-12 19:39:20 +00:00
// are custom menus active?
bool menuProcessed = false ;
if ( pPlayer )
2014-02-21 13:43:32 +00:00
// adjust by viewport X/Y because the GUI windows calculate their positions (and thus check input) based on that
2014-10-13 16:48:03 +00:00
menuProcessed = : : Game . ScriptGuiRoot - > MouseInput ( iButton , iX , iY , dwKeyFlags ) ;
2014-10-11 09:29:02 +00:00
if ( menuProcessed )
Cursor = C4MC_Cursor_Select ;
2013-02-12 19:39:20 +00:00
// if not caught by a menu
if ( ! menuProcessed )
// script handling of mouse control for everything but regular movement (which is sent at control frame intervals only)
if ( iButton ! = C4MC_Button_None )
// not if blocked by selection object
if ( ! TargetObject )
// safety (can't really happen in !IsPassive, but w/e
if ( pPlayer & & pPlayer - > ControlSet )
if ( ! menuProcessed & & pPlayer - > ControlSet - > IsMouseControlAssigned ( iButton ) )
2018-01-17 23:40:39 +00:00
pPlayer - > Control . DoMouseInput ( 0 /* only 1 mouse supported so far */ , iButton , GameX , GameY , GuiX , GuiY , dwKeyFlags ) ;
2009-10-17 15:53:26 +00:00
}
void C4MouseControl : : DoMoveInput ( )
{
// current mouse move to input queue
// do sanity checks
if ( ! Active | | ! fMouseOwned ) return ;
if ( ! ( pPlayer = : : Players . Get ( Player ) ) ) return ;
if ( ! pPlayer - > ControlSet ) return ;
if ( ! pPlayer - > ControlSet - > IsMouseControlAssigned ( C4MC_Button_None ) ) return ;
2018-01-17 23:40:39 +00:00
pPlayer - > Control . DoMouseInput ( 0 /* only 1 mouse supported so far */ , C4MC_Button_None , GameX , GameY , GuiX , GuiY , ( ControlDown & & MK_CONTROL ) | ( ShiftDown & & MK_SHIFT ) | ( AltDown & & MK_ALT ) ) ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : Draw ( C4TargetFacet & cgo , const ZoomData & GameZoom )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
int32_t iOffsetX , iOffsetY ;
2016-05-22 22:20:37 +00:00
float wdt = GfxR - > fctMouseCursor . Wdt , hgt = GfxR - > fctMouseCursor . Hgt ;
// Cursor size relative to height - does not matter with current square graphics.
float zoom = Config . Graphics . MouseCursorSize / hgt ;
hgt * = zoom ;
wdt * = zoom ;
2009-05-08 13:28:41 +00:00
ZoomData GuiZoom ;
2011-10-03 14:30:18 +00:00
pDraw - > GetZoom ( & GuiZoom ) ;
2009-05-08 13:28:41 +00:00
// Hidden
if ( ! Visible | | ! fMouseOwned ) return ;
// Draw selection
if ( ! IsPassive ( ) )
2009-10-16 21:07:43 +00:00
{
2010-09-24 17:51:34 +00:00
Selection . DrawSelectMark ( cgo ) ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
// Draw control
switch ( Drag )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2012-11-16 16:29:42 +00:00
case C4MC_Drag_None : case C4MC_Drag_Script : case C4MC_Drag_Unhandled :
2010-03-28 18:58:01 +00:00
// Hotspot offset: Usually, hotspot is in center
2016-05-22 22:20:37 +00:00
iOffsetX = wdt / 2 ;
iOffsetY = hgt / 2 ;
2010-07-06 00:10:54 +00:00
// calculate the hotspot for the scrolling cursors
switch ( Cursor )
2010-03-28 18:58:01 +00:00
{
2016-05-22 22:20:37 +00:00
case C4MC_Cursor_Up : iOffsetY + = - hgt / 2 ; break ;
case C4MC_Cursor_Down : iOffsetY + = + hgt / 2 ; break ;
case C4MC_Cursor_Left : iOffsetX + = - wdt / 2 ; break ;
case C4MC_Cursor_Right : iOffsetX + = + wdt / 2 ; break ;
case C4MC_Cursor_UpLeft : iOffsetX + = - wdt / 2 ; iOffsetY + = - hgt / 2 ; break ;
case C4MC_Cursor_UpRight : iOffsetX + = + wdt / 2 ; iOffsetY + = - hgt / 2 ; break ;
case C4MC_Cursor_DownLeft : iOffsetX + = - wdt / 2 ; iOffsetY + = + hgt / 2 ; break ;
case C4MC_Cursor_DownRight : iOffsetX + = + wdt / 2 ; iOffsetY + = + hgt / 2 ; break ;
2010-03-28 18:58:01 +00:00
}
// Drag image
2011-12-25 18:16:50 +00:00
if ( DragImageObject | | DragImageDef )
2010-03-28 18:58:01 +00:00
{
2011-12-25 18:16:50 +00:00
C4DefGraphics * pGfx ;
if ( DragImageObject )
pGfx = DragImageObject - > GetGraphics ( ) ;
else
pGfx = & DragImageDef - > Graphics ;
// Determine image boundaries
float ImageWdt ;
float ImageHgt ;
if ( pGfx - > Type = = C4DefGraphics : : TYPE_Bitmap )
{
2011-12-29 16:32:40 +00:00
C4Def * Def = ( DragImageObject ? DragImageObject - > Def : DragImageDef ) ;
ImageWdt = Def - > PictureRect . Wdt ;
ImageHgt = Def - > PictureRect . Hgt ;
2011-12-25 18:16:50 +00:00
}
2015-01-17 17:10:21 +00:00
else if ( pGfx - > Type = = C4DefGraphics : : TYPE_Mesh )
2011-12-25 18:16:50 +00:00
{
// Note bounding box is in OGRE coordinate system
ImageWdt = pGfx - > Mesh - > GetBoundingBox ( ) . y2 - pGfx - > Mesh - > GetBoundingBox ( ) . y1 ;
ImageHgt = pGfx - > Mesh - > GetBoundingBox ( ) . z2 - pGfx - > Mesh - > GetBoundingBox ( ) . z1 ;
}
2015-01-17 17:10:21 +00:00
else
{
ImageWdt = ImageHgt = 1.0f ;
}
2011-12-25 18:16:50 +00:00
2010-03-28 18:58:01 +00:00
// zoom mode: Drag in GUI or Game depending on source object
bool fIsGameZoom = true ;
if ( Drag = = C4MC_Drag_Script & & DragObject & & ( DragObject - > Category & C4D_Foreground ) )
fIsGameZoom = false ;
// drag image in game zoom
float XDraw , YDraw , ZoomDraw ;
if ( fIsGameZoom )
2009-10-16 21:07:43 +00:00
{
2011-10-03 14:30:18 +00:00
pDraw - > SetZoom ( GameZoom ) ;
2010-03-28 18:58:01 +00:00
XDraw = GameX ; YDraw = GameY ;
ZoomDraw = 1.0f ;
2009-10-16 21:07:43 +00:00
}
2010-03-28 18:58:01 +00:00
else
{
2011-12-25 18:16:50 +00:00
ZoomDraw = std : : min ( 64.0f / ImageWdt , 64.0f / ImageHgt ) ;
2010-03-28 18:58:01 +00:00
XDraw = GuiX ; YDraw = GuiY ;
}
2011-12-25 18:16:50 +00:00
iOffsetX = int ( ZoomDraw * ImageWdt / 2 ) ;
2012-11-16 16:29:42 +00:00
iOffsetY = int ( ZoomDraw * ImageHgt / 2 ) ;
2011-12-25 18:16:50 +00:00
C4TargetFacet ccgo ;
ccgo . Set ( cgo . Surface , XDraw + cgo . X - iOffsetX , YDraw + cgo . Y - iOffsetY , float ( ImageWdt ) * ZoomDraw , float ( ImageHgt ) * ZoomDraw ) ;
if ( DragImageObject )
{
uint32_t ColorMod = DragImageObject - > ColorMod ;
uint32_t BlitMode = DragImageObject - > BlitMode ;
2017-05-03 18:28:00 +00:00
DragImageObject - > ColorMod = ( Drag = = C4MC_Drag_Script ) ? 0x7fffffff : ( /*DragImagePhase*/ false ? 0x8f7f0000 : 0x1f007f00 ) ;
2011-12-25 18:16:50 +00:00
DragImageObject - > BlitMode = C4GFXBLIT_MOD2 ;
2013-02-12 19:39:20 +00:00
2016-11-02 23:58:02 +00:00
DragImageObject - > DrawPicture ( ccgo , false , nullptr ) ;
2011-12-25 18:16:50 +00:00
DragImageObject - > ColorMod = ColorMod ;
DragImageObject - > BlitMode = BlitMode ;
}
2010-03-28 18:58:01 +00:00
else
2011-12-25 18:16:50 +00:00
{
// draw in special modulation mode
pDraw - > SetBlitMode ( C4GFXBLIT_MOD2 ) ;
// draw DragImage in red or green, according to the phase to be used
2017-05-03 18:28:00 +00:00
pDraw - > ActivateBlitModulation ( ( Drag = = C4MC_Drag_Script ) ? 0x7fffffff : ( /*DragImagePhase*/ false ? 0x8f7f0000 : 0x1f007f00 ) ) ;
2011-12-25 18:16:50 +00:00
2016-11-02 23:58:02 +00:00
DragImageDef - > Draw ( ccgo , false , pPlayer ? pPlayer - > ColorDw : 0xff0000ff , nullptr , 0 , 0 , nullptr ) ;
2011-12-25 18:16:50 +00:00
// reset color
pDraw - > DeactivateBlitModulation ( ) ;
pDraw - > SetBlitMode ( 0 ) ;
}
2011-10-03 14:30:18 +00:00
if ( fIsGameZoom ) pDraw - > SetZoom ( GuiZoom ) ;
2010-03-28 18:58:01 +00:00
// reset cursor hotspot offset for script drawing
2016-05-22 22:20:37 +00:00
iOffsetX = wdt / 2 ;
iOffsetY = hgt / 2 ;
2010-03-28 18:58:01 +00:00
}
// Cursor
2011-12-25 18:16:50 +00:00
if ( ( ! DragImageDef & & ! DragImageObject ) | | ( Drag = = C4MC_Drag_Script ) )
2016-05-22 22:20:37 +00:00
{
GfxR - > fctMouseCursor . DrawX ( cgo . Surface , cgo . X + GuiX - iOffsetX , cgo . Y + GuiY - iOffsetY , wdt , hgt , Cursor ) ;
}
2010-03-28 18:58:01 +00:00
break ;
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
// Draw caption
2012-04-15 10:09:54 +00:00
if ( Caption & & : : pGUI )
2009-10-16 21:07:43 +00:00
{
2012-04-15 10:09:54 +00:00
C4TargetFacet cgoTip ;
cgoTip = static_cast < const C4Facet & > ( cgo ) ;
C4GUI : : Screen : : DrawToolTip ( Caption . getData ( ) , cgoTip , cgo . X + GuiX , cgo . Y + GuiY ) ;
2009-05-08 13:28:41 +00:00
}
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : UpdateCursorTarget ( )
2009-10-16 21:07:43 +00:00
{
2012-02-25 20:56:11 +00:00
C4Object * OldTargetObject = TargetObject ;
2009-05-08 13:28:41 +00:00
2012-02-25 20:56:11 +00:00
if ( Scrolling )
2009-10-16 21:07:43 +00:00
{
2012-02-25 20:56:11 +00:00
// Scrolling: no other target
2016-11-02 23:58:02 +00:00
TargetObject = nullptr ;
2012-02-25 20:56:11 +00:00
}
else
{
// Target object
TargetObject = GetTargetObject ( ) ;
2016-11-02 23:58:02 +00:00
if ( TargetObject & & FogOfWar & & ! ( TargetObject - > Category & C4D_IgnoreFoW ) ) TargetObject = nullptr ;
2009-05-08 13:28:41 +00:00
2012-02-25 20:56:11 +00:00
// Movement
if ( ! FogOfWar & & ! IsPassive ( ) ) Cursor = C4MC_Cursor_Crosshair ;
2009-05-08 13:28:41 +00:00
2012-02-25 20:56:11 +00:00
// Target action
if ( TargetObject & & ! IsPassive ( ) )
{
// default cursor for object; also set if not in FoW
Cursor = C4MC_Cursor_Crosshair ;
// select custom region. Can select an object if it does not have the MD_NoClick
// flag set. If we are currently dragging then selection depends on it being a drop target.
bool CanSelect ;
if ( Drag = = C4MC_Drag_Script )
CanSelect = ( TargetObject - > GetPropertyInt ( P_MouseDrag ) & C4MC_MD_DropTarget ) ! = 0 ;
else
CanSelect = ( TargetObject - > GetPropertyInt ( P_MouseDrag ) & C4MC_MD_NoClick ) = = 0 ;
2011-12-28 18:33:19 +00:00
2012-02-25 20:56:11 +00:00
if ( ( TargetObject - > Category & C4D_MouseSelect ) & & CanSelect )
Cursor = C4MC_Cursor_Select ;
else
2016-11-02 23:58:02 +00:00
TargetObject = nullptr ;
2012-02-25 20:56:11 +00:00
}
2010-03-28 18:58:01 +00:00
2012-02-25 20:56:11 +00:00
// passive cursor
2012-04-15 10:09:54 +00:00
if ( IsPassive ( ) )
2012-11-16 16:29:42 +00:00
Cursor = C4MC_Cursor_Passive ;
2010-03-28 18:58:01 +00:00
2014-10-11 09:29:02 +00:00
// update tooltip information
if ( OldTargetObject ! = TargetObject )
2009-10-16 21:07:43 +00:00
{
2014-12-26 10:51:02 +00:00
C4String * newTooltip = nullptr ;
if ( TargetObject & & ( Cursor = = C4MC_Cursor_Select ) & & ( TargetObject - > Category & C4D_MouseSelect ) & & ( newTooltip = TargetObject - > GetPropertyStr ( P_Tooltip ) ) )
2009-10-16 21:07:43 +00:00
{
2014-10-11 09:29:02 +00:00
float objX , objY ;
TargetObject - > GetViewPos ( objX , objY , - fctViewportGUI . X , - fctViewportGUI . Y , fctViewportGUI ) ;
objX + = TargetObject - > Shape . x ;
objY + = TargetObject - > Shape . y - TargetObject - > addtop ( ) ;
SetTooltipRectangle ( C4Rect ( objX , objY , TargetObject - > Shape . Wdt , TargetObject - > Shape . Hgt + TargetObject - > addtop ( ) ) ) ;
2014-12-26 10:51:02 +00:00
SetTooltipText ( StdStrBuf ( newTooltip - > GetCStr ( ) ) ) ;
2014-10-11 09:29:02 +00:00
}
else
{
SetTooltipRectangle ( C4Rect ( 0 , 0 , 0 , 0 ) ) ;
}
}
if ( ! KeepCaption
& & ToolTipRectangle . Wdt ! = 0
& & Inside ( GuiX , ToolTipRectangle . x , ToolTipRectangle . x + ToolTipRectangle . Wdt )
& & Inside ( GuiY , ToolTipRectangle . y , ToolTipRectangle . y + ToolTipRectangle . Hgt ) )
{
+ + TimeInTooltipRectangle ;
if ( TimeInTooltipRectangle > = C4MC_Tooltip_Delay )
{
Caption = TooltipText ;
2012-02-25 20:56:11 +00:00
}
2009-05-08 13:28:41 +00:00
}
2012-02-25 20:56:11 +00:00
else
2014-10-11 09:29:02 +00:00
{
// disable tooltip pop-up; whatever set it in the first place will set it again on the next mouse-enter
TimeInTooltipRectangle = 0 ;
ToolTipRectangle . Wdt = 0 ;
}
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
2012-02-25 20:56:11 +00:00
// Make a script callback if the object being hovered changes
2014-11-08 01:16:30 +00:00
if ( ! IsPassive ( ) & & OldTargetObject ! = TargetObject )
2012-02-25 20:56:11 +00:00
{
// TODO: This might put a heavy load on the network, depending on the number of
// selectable objects around. If it turns out to be a problem we might want to
// deduce these hover callbacks client-side instead.
// Or, make sure to send this at most once per control frame.
2013-09-04 17:58:57 +00:00
Game . Input . Add ( CID_PlrMouseMove , C4ControlPlayerMouse : : Hover ( : : Players . Get ( Player ) , TargetObject , OldTargetObject , DragObject ) ) ;
2012-02-25 20:56:11 +00:00
}
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
int32_t C4MouseControl : : UpdateSingleSelection ( )
2010-03-28 18:58:01 +00:00
{
2009-10-16 21:07:43 +00:00
// Set single selection if cursor on selection object (clear prior object selection)
2009-05-08 13:28:41 +00:00
if ( TargetObject & & ( Cursor = = C4MC_Cursor_Select ) )
2010-03-28 18:58:01 +00:00
{ Selection . Clear ( ) ; Selection . Add ( TargetObject , C4ObjectList : : stNone ) ; }
2009-05-08 13:28:41 +00:00
2009-10-16 21:07:43 +00:00
// Cursor has moved off single object (or target object) selection: clear selection
2009-05-08 13:28:41 +00:00
else if ( Selection . GetObject ( ) )
2009-06-12 23:09:32 +00:00
if ( : : Players . Get ( Player ) - > ObjectInCrew ( Selection . GetObject ( ) )
2010-03-28 18:58:01 +00:00
| | ( Selection . GetObject ( ) - > Category & C4D_MouseSelect ) )
2009-05-08 13:28:41 +00:00
Selection . Clear ( ) ;
return Selection . ObjectCount ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : UpdateScrolling ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Assume no scrolling
Scrolling = false ;
2010-09-08 21:49:42 +00:00
// No scrolling if disabled by player
if ( pPlayer ) if ( pPlayer - > IsViewLocked ( ) ) return ;
2009-05-08 13:28:41 +00:00
// Scrolling on border
if ( VpX = = 0 )
2010-09-24 17:52:20 +00:00
{ Cursor = C4MC_Cursor_Left ; ScrollView ( - ScrollSpeed / Viewport - > Zoom , 0 , Viewport - > ViewWdt / Viewport - > Zoom , Viewport - > ViewHgt / Viewport - > Zoom ) ; Scrolling = true ; }
2009-05-08 13:28:41 +00:00
if ( VpY = = 0 )
2010-09-24 17:52:20 +00:00
{ Cursor = C4MC_Cursor_Up ; ScrollView ( 0 , - ScrollSpeed / Viewport - > Zoom , Viewport - > ViewWdt / Viewport - > Zoom , Viewport - > ViewHgt / Viewport - > Zoom ) ; Scrolling = true ; }
2009-05-08 13:28:41 +00:00
if ( VpX = = Viewport - > ViewWdt - 1 )
2010-09-24 17:52:20 +00:00
{ Cursor = C4MC_Cursor_Right ; ScrollView ( + ScrollSpeed / Viewport - > Zoom , 0 , Viewport - > ViewWdt / Viewport - > Zoom , Viewport - > ViewHgt / Viewport - > Zoom ) ; Scrolling = true ; }
2009-05-08 13:28:41 +00:00
if ( VpY = = Viewport - > ViewHgt - 1 )
2010-09-24 17:52:20 +00:00
{ Cursor = C4MC_Cursor_Down ; ScrollView ( 0 , + ScrollSpeed / Viewport - > Zoom , Viewport - > ViewWdt / Viewport - > Zoom , Viewport - > ViewHgt / Viewport - > Zoom ) ; Scrolling = true ; }
2009-05-08 13:28:41 +00:00
// Set correct cursor
2010-03-28 18:58:01 +00:00
if ( ( VpX = = 0 ) & & ( VpY = = 0 ) ) Cursor = C4MC_Cursor_UpLeft ;
if ( ( VpX = = Viewport - > ViewWdt - 1 ) & & ( VpY = = 0 ) ) Cursor = C4MC_Cursor_UpRight ;
if ( ( VpX = = 0 ) & & ( VpY = = Viewport - > ViewHgt - 1 ) ) Cursor = C4MC_Cursor_DownLeft ;
if ( ( VpX = = Viewport - > ViewWdt - 1 ) & & ( VpY = = Viewport - > ViewHgt - 1 ) ) Cursor = C4MC_Cursor_DownRight ;
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : LeftDown ( )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// Set flag
LeftButtonDown = true ;
// Store down values (same MoveRightDown -> use StoreDown)
DownX = GameX ; DownY = GameY ;
DownTarget = TargetObject ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : LeftUp ( )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// Ignore left up after double click
2012-10-14 17:35:30 +00:00
if ( LeftDoubleIgnoreUp )
2009-10-16 21:07:43 +00:00
{
2012-10-14 17:35:30 +00:00
LeftDoubleIgnoreUp = false ;
}
else
{
// Evaluate by drag status
switch ( Drag )
{
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2012-10-14 17:35:30 +00:00
case C4MC_Drag_Unhandled : // nobreak
case C4MC_Drag_None : LeftUpDragNone ( ) ; break ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MC_Drag_Script : ButtonUpDragScript ( ) ; break ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
2009-05-08 13:28:41 +00:00
}
2012-10-14 17:35:30 +00:00
// Update status flag
LeftButtonDown = false ;
2016-11-02 23:58:02 +00:00
if ( ! RightButtonDown ) DownTarget = nullptr ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : DragNone ( )
2009-12-30 19:16:32 +00:00
{
// Cursor movement
UpdateCursorTarget ( ) ;
// Update selection
UpdateSingleSelection ( ) ;
2009-05-08 13:28:41 +00:00
// Button down: begin drag
if ( ( LeftButtonDown | | RightButtonDown )
2010-03-28 18:58:01 +00:00
& & ( ( Abs ( GameX - DownX ) > C4MC_DragSensitivity ) | | ( Abs ( GameY - DownY ) > C4MC_DragSensitivity ) ) )
2009-12-30 19:16:32 +00:00
{
bool fAllowDrag = true ;
// check if target object allows scripted dragging
2012-02-25 21:15:39 +00:00
if ( fAllowDrag & & DownTarget & & ( ! FogOfWar | | ( DownTarget - > Category & C4D_IgnoreFoW ) ) )
2009-12-30 19:16:32 +00:00
{
2013-03-03 18:25:18 +00:00
C4Object * drag_image_obj ; C4Def * drag_image_def ;
2011-12-28 18:33:19 +00:00
// Drag only if MD_SOURCE is set and drag image is present
2012-02-25 21:05:47 +00:00
if ( ( DownTarget - > GetPropertyInt ( P_MouseDrag ) & C4MC_MD_DragSource ) & &
2013-03-03 18:25:18 +00:00
DownTarget - > GetDragImage ( & drag_image_obj , & drag_image_def ) )
2009-12-30 19:16:32 +00:00
{
Drag = C4MC_Drag_Script ;
2011-12-25 18:16:50 +00:00
if ( drag_image_obj ) DragImageObject = drag_image_obj ;
2013-03-03 18:25:18 +00:00
else DragImageDef = drag_image_def ;
2011-12-25 18:16:50 +00:00
2012-02-25 21:05:47 +00:00
DragObject = DownTarget ;
2009-05-08 13:28:41 +00:00
}
}
2010-04-18 08:51:50 +00:00
// dragging somewhere unhandled - mark drag process so moving over a draggable object won't start a drag
if ( Drag = = C4MC_Drag_None )
{
Drag = C4MC_Drag_Unhandled ;
}
2009-05-08 13:28:41 +00:00
}
2009-12-30 19:16:32 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : LeftDouble ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Update status flag
LeftButtonDown = false ;
// Set ignore flag for next left up
LeftDoubleIgnoreUp = true ;
// Evaluate left double by drag status (can only be C4MC_Drag_None really)
switch ( Drag )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-03-28 18:58:01 +00:00
case C4MC_Drag_None :
// Double left click (might be on a target)
break ;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : RightDown ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Update status flag
RightButtonDown = true ;
// Store down values (same MoveLeftDown -> use StoreDown)
DownX = GameX ; DownY = GameY ;
DownTarget = TargetObject ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : RightUp ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Evaluate by drag status
switch ( Drag )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-04-18 08:51:50 +00:00
case C4MC_Drag_Unhandled : // nobreak
2010-03-28 18:58:01 +00:00
case C4MC_Drag_None : RightUpDragNone ( ) ; break ;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-03-28 18:58:01 +00:00
case C4MC_Drag_Script : ButtonUpDragScript ( ) ; break ;
2009-12-30 19:16:32 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2009-05-08 13:28:41 +00:00
}
2012-10-14 17:35:30 +00:00
// Update status flag
RightButtonDown = false ;
2016-11-02 23:58:02 +00:00
if ( ! LeftButtonDown ) DownTarget = nullptr ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : Wheel ( DWORD dwFlags )
2010-03-28 18:58:01 +00:00
{
}
2009-05-08 13:28:41 +00:00
2009-12-30 19:16:32 +00:00
void C4MouseControl : : DragScript ( )
{
// script drag should update target and selection so selection highlight on drop target is visible
// Cursor movement
UpdateCursorTarget ( ) ;
// Update selection
UpdateSingleSelection ( ) ;
Cursor = C4MC_Cursor_DragDrop ;
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : LeftUpDragNone ( )
2010-03-28 18:58:01 +00:00
{
2010-04-18 08:51:50 +00:00
// might be in Drag_Unknown
Drag = C4MC_Drag_None ;
2009-05-08 13:28:41 +00:00
// Single left click (might be on a target)
switch ( Cursor )
2010-03-28 18:58:01 +00:00
{
case C4MC_Cursor_Select :
// Object selection to control queue
2012-10-14 17:35:30 +00:00
if ( ! IsPassive ( ) & & Selection . GetObject ( ) = = DownTarget )
Game . Input . Add ( CID_PlrSelect , new C4ControlPlayerSelect ( Player , Selection , false ) ) ;
2010-03-28 18:58:01 +00:00
break ;
default :
// done in script
break ;
}
2009-05-08 13:28:41 +00:00
// Clear selection
Selection . Clear ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-12-30 19:16:32 +00:00
void C4MouseControl : : ButtonUpDragScript ( )
{
2012-04-01 17:48:11 +00:00
// Determine drag+drop targets
UpdateCursorTarget ( ) ;
2009-12-30 19:16:32 +00:00
// Finish drag
Drag = C4MC_Drag_None ;
2010-01-25 03:14:52 +00:00
DragID = C4ID : : None ;
2016-11-02 23:58:02 +00:00
DragImageObject = nullptr ;
DragImageDef = nullptr ;
2009-12-30 19:16:32 +00:00
C4Object * DragObject = this - > DragObject ;
2016-11-02 23:58:02 +00:00
this - > DragObject = nullptr ;
2009-12-30 19:16:32 +00:00
C4Object * DropObject = TargetObject ;
// drag object must exist; drop object is optional
if ( ! DragObject ) return ;
2011-12-28 18:33:19 +00:00
if ( DropObject & & ( ~ DropObject - > GetPropertyInt ( P_MouseDrag ) & C4MC_MD_DropTarget ) )
2016-11-02 23:58:02 +00:00
DropObject = nullptr ;
2009-12-30 19:16:32 +00:00
// no commands if player is eliminated or doesn't exist any more
C4Player * pPlr = : : Players . Get ( Player ) ;
if ( ! pPlr | | pPlr - > Eliminated ) return ;
// todo: Perform drag/drop validity check
// now drag/drop is handled by script
2013-09-04 17:58:57 +00:00
Game . Input . Add ( CID_PlrMouseMove , C4ControlPlayerMouse : : DragDrop ( : : Players . Get ( Player ) , DropObject , DragObject ) ) ;
2009-12-30 19:16:32 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : RightUpDragNone ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
2010-04-18 08:51:50 +00:00
// might be in Drag_Unknown
Drag = C4MC_Drag_None ;
2009-12-29 17:54:39 +00:00
// Alternative object selection
2012-10-14 17:35:30 +00:00
if ( Cursor = = C4MC_Cursor_Select & & ! IsPassive ( ) & & Selection . GetObject ( ) = = DownTarget )
2009-12-29 17:54:39 +00:00
{ Game . Input . Add ( CID_PlrSelect , new C4ControlPlayerSelect ( Player , Selection , true ) ) ; }
2009-10-16 21:07:43 +00:00
// TODO: Evaluate right click
2009-05-08 13:28:41 +00:00
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : UpdateFogOfWar ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Assume no fog of war
FogOfWar = false ;
// Check for fog of war
2014-11-07 16:53:10 +00:00
// TODO: Check C4FoWRegion... should maybe be passed as a parameter?
// pDraw->GetFoW() might not be current at this time.
2016-04-02 15:50:49 +00:00
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 ( ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
FogOfWar = true ;
// allow dragging, scrolling, region selection and manipulations of objects not affected by FoW
2012-11-16 16:29:42 +00:00
if ( ! Scrolling & & ( ! TargetObject | | ! ( TargetObject - > Category & C4D_IgnoreFoW ) ) )
2010-03-28 18:58:01 +00:00
{
2012-11-16 16:29:42 +00:00
Cursor = C4MC_Cursor_Passive ;
2009-05-08 13:28:41 +00:00
}
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : ShowCursor ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Visible = true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : HideCursor ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Visible = false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char * C4MouseControl : : GetCaption ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
return Caption . getData ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2014-10-11 09:29:02 +00:00
void C4MouseControl : : SetTooltipRectangle ( const C4Rect & rectangle )
{
// Set the tooltip rectangle slightly larger than originally requested.
// 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
// in case the GUI item uses a different check for bounds (< vs <=) than the tooltip rectangle.
ToolTipRectangle = C4Rect ( rectangle . x - 2 , rectangle . y - 2 , rectangle . Wdt + 4 , rectangle . Hgt + 4 ) ;
TimeInTooltipRectangle = 0 ;
}
void C4MouseControl : : SetTooltipText ( const StdStrBuf & text )
{
TooltipText = text ;
}
2009-10-16 21:07:43 +00:00
C4Object * C4MouseControl : : GetTargetObject ( )
{
2009-05-08 13:28:41 +00:00
// find object
2009-10-16 21:07:43 +00:00
// gui object position currently wrong...will fall apart once GUIZoom is activated
2012-04-15 10:09:54 +00:00
C4Object * pObj = Game . FindVisObject ( ViewX , ViewY , Player , fctViewportGame , fctViewportGUI , GameX , GameY , C4D_MouseSelect , GuiX - fctViewportGUI . X , GuiY - fctViewportGUI . Y ) ;
2016-11-02 23:58:02 +00:00
if ( ! pObj ) return nullptr ;
2009-05-08 13:28:41 +00:00
return pObj ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
bool C4MouseControl : : IsPassive ( )
2010-03-28 18:58:01 +00:00
{
2009-06-15 22:06:37 +00:00
return : : Control . isReplay ( ) | | Player < = NO_OWNER ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2010-09-24 17:52:20 +00:00
void C4MouseControl : : ScrollView ( float iX , float iY , float ViewWdt , float ViewHgt )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// player assigned: scroll player view
if ( pPlayer )
pPlayer - > ScrollView ( iX , iY , ViewWdt , ViewHgt ) ;
else if ( Viewport )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// no player: Scroll fullscreen viewport
2015-01-03 21:51:02 +00:00
Viewport - > ScrollView ( iX , iY ) ;
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MouseControl : : IsDragging ( )
2010-03-28 18:58:01 +00:00
{
2012-11-16 16:29:42 +00:00
return Active & & Drag = = C4MC_Drag_Script ;
2010-03-28 18:58:01 +00:00
}
2010-04-10 20:44:00 +00:00
2016-08-07 15:08:42 +00:00
bool C4MouseControl : : GetLastCursorPos ( int32_t * x_out_gui , int32_t * y_out_gui , int32_t * x_out_game , int32_t * y_out_game ) const
2010-04-10 20:44:00 +00:00
{
// safety
if ( ! Active | | ! fMouseOwned ) return false ;
// OK; assign last known pos
2016-08-07 15:08:42 +00:00
* x_out_gui = GuiX ; * y_out_gui = GuiY ;
* x_out_game = GameX ; * y_out_game = GameY ;
2010-04-10 20:44:00 +00:00
return true ;
2010-09-24 17:52:20 +00:00
}