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/
* Copyright ( c ) 2009 - 2013 , 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 */
# include <C4Include.h>
# include <C4MouseControl.h>
2011-03-03 16:10:22 +00:00
# include <C4DefList.h>
2009-05-08 13:28:41 +00:00
# include <C4Viewport.h>
# include <C4Object.h>
# include <C4Command.h>
# include <C4Application.h>
# include <C4FullScreen.h>
# include <C4Gui.h>
2009-06-12 18:52:21 +00:00
# include <C4Landscape.h>
# include <C4Game.h>
2009-05-08 13:28:41 +00:00
# include <C4Player.h>
# include "C4ChatDlg.h"
2009-06-12 18:52:21 +00:00
# include <C4GraphicsResource.h>
# include <C4GraphicsSystem.h>
2009-06-12 23:09:32 +00:00
# include <C4PlayerList.h>
2009-06-15 21:47:26 +00:00
# include <C4GameObjects.h>
2009-06-15 22:06:37 +00:00
# include <C4GameControl.h>
2013-05-09 11:28:45 +00:00
# include <C4GuiWindow.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 ;
const int32_t C4MC_Cursor_Select = 0 , // click cursor to select/click stuff in the GUI
C4MC_Cursor_Crosshair = 1 , // standard ingame cursor
C4MC_Cursor_DragDrop = 3 , // cursor when drag&dropping
C4MC_Cursor_Up = 4 , // cursors for scrolling the viewport ...
C4MC_Cursor_Down = 5 , // ...
C4MC_Cursor_Left = 6 ,
C4MC_Cursor_Right = 7 ,
C4MC_Cursor_UpLeft = 8 ,
C4MC_Cursor_UpRight = 9 ,
C4MC_Cursor_DownLeft = 10 ,
C4MC_Cursor_DownRight = 11 ,
C4MC_Cursor_Passive = 12 ; // passive cursor in records and an fog of war
2010-03-28 18:58:01 +00:00
const int32_t C4MC_Time_on_Target = 10 ;
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 ;
pPlayer = NULL ;
Viewport = NULL ;
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 ;
2009-12-30 19:16:32 +00:00
DragObject = NULL ;
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 ( ) ;
TargetObject = DownTarget = NULL ;
TimeOnTargetObject = 0 ;
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 ;
2011-12-25 18:16:50 +00:00
DragImageDef = NULL ;
DragImageObject = NULL ;
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 ;
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
{
2009-05-08 13:28:41 +00:00
if ( TargetObject = = pObj ) TargetObject = NULL ;
if ( DownTarget = = pObj ) DownTarget = NULL ;
2009-12-30 19:16:32 +00:00
if ( DragObject = = pObj )
{
DragObject = NULL ;
Drag = C4MC_Drag_None ;
2011-12-25 18:16:50 +00:00
DragImageDef = NULL ;
DragImageObject = NULL ;
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
2010-10-29 23:47:50 +00:00
if ( ! Active | | ! Application . Active | | : : pGUI - > HasMouseFocus ( ) ) { ClipCursor ( NULL ) ; 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 ) ;
2009-05-08 13:28:41 +00:00
if ( ! pVP ) { ClipCursor ( NULL ) ; return ; }
// 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
pPlayer = NULL ;
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 ( ) ;
fctViewport . Set ( NULL , rcViewport . x , rcViewport . y , rcViewport . Wdt , rcViewport . Hgt ) ;
ViewX = Viewport - > ViewX ; ViewY = Viewport - > ViewY ;
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 ;
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;
//FIXMESetCursorPos(iMidX, iMidY);
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
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 )
2013-05-26 16:12:03 +00:00
menuProcessed = : : Game . GuiWindowRoot - > MouseInput ( Player , iButton , iX , iY , dwKeyFlags ) ;
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 )
2009-10-17 15:53:26 +00:00
{
2013-02-12 19:39:20 +00:00
if ( ! menuProcessed & & pPlayer - > ControlSet - > IsMouseControlAssigned ( iButton ) )
{
int wheel_dir = 0 ;
if ( iButton = = C4MC_Button_Wheel ) wheel_dir = ( short ) ( dwKeyFlags > > 16 ) ;
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 ) ;
}
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 ;
2012-04-22 20:09:06 +00:00
pPlayer - > Control . DoMouseInput ( 0 /* only 1 mouse supported so far */ , C4MC_Button_None , GameX , GameY , GuiX , GuiY , ControlDown , ShiftDown , AltDown , 0 ) ;
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 ;
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
iOffsetX = GfxR - > fctMouseCursor . Wdt / 2 ;
iOffsetY = GfxR - > fctMouseCursor . 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
{
2010-07-06 00:10:54 +00:00
case C4MC_Cursor_Up : iOffsetY + = - GfxR - > fctMouseCursor . Hgt / 2 ; break ;
case C4MC_Cursor_Down : iOffsetY + = + GfxR - > fctMouseCursor . Hgt / 2 ; break ;
case C4MC_Cursor_Left : iOffsetX + = - GfxR - > fctMouseCursor . Wdt / 2 ; break ;
case C4MC_Cursor_Right : iOffsetX + = + GfxR - > fctMouseCursor . Wdt / 2 ; break ;
case C4MC_Cursor_UpLeft : iOffsetX + = - GfxR - > fctMouseCursor . Wdt / 2 ; iOffsetY + = - GfxR - > fctMouseCursor . Hgt / 2 ; break ;
case C4MC_Cursor_UpRight : iOffsetX + = + GfxR - > fctMouseCursor . Wdt / 2 ; iOffsetY + = - GfxR - > fctMouseCursor . Hgt / 2 ; break ;
case C4MC_Cursor_DownLeft : iOffsetX + = - GfxR - > fctMouseCursor . Wdt / 2 ; iOffsetY + = + GfxR - > fctMouseCursor . Hgt / 2 ; break ;
case C4MC_Cursor_DownRight : iOffsetX + = + GfxR - > fctMouseCursor . Wdt / 2 ; iOffsetY + = + GfxR - > fctMouseCursor . 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
}
else
{
// 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 ;
}
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 ;
DragImageObject - > ColorMod = ( Drag = = C4MC_Drag_Script ) ? 0x7fffffff : ( /*DragImagePhase*/ 0 ? 0x8f7f0000 : 0x1f007f00 ) ;
DragImageObject - > BlitMode = C4GFXBLIT_MOD2 ;
2013-02-12 19:39:20 +00:00
2012-11-16 16:29:42 +00:00
DragImageObject - > DrawPicture ( ccgo , false , NULL ) ;
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
pDraw - > ActivateBlitModulation ( ( Drag = = C4MC_Drag_Script ) ? 0x7fffffff : ( /*DragImagePhase*/ 0 ? 0x8f7f0000 : 0x1f007f00 ) ) ;
DragImageDef - > Draw ( ccgo , false , pPlayer ? pPlayer - > ColorDw : 0xff0000ff , NULL , 0 , 0 , NULL ) ;
// 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
iOffsetX = GfxR - > fctMouseCursor . Wdt / 2 ;
iOffsetY = GfxR - > fctMouseCursor . Hgt / 2 ;
}
// Cursor
2011-12-25 18:16:50 +00:00
if ( ( ! DragImageDef & & ! DragImageObject ) | | ( Drag = = C4MC_Drag_Script ) )
2010-03-28 18:58:01 +00:00
GfxR - > fctMouseCursor . Draw ( cgo . Surface , cgo . X + GuiX - iOffsetX , cgo . Y + GuiY - iOffsetY , Cursor ) ;
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
TargetObject = NULL ;
}
else
{
// Target object
TargetObject = GetTargetObject ( ) ;
if ( TargetObject & & FogOfWar & & ! ( TargetObject - > Category & C4D_IgnoreFoW ) ) TargetObject = NULL ;
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
TargetObject = NULL ;
}
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
2012-02-25 20:56:11 +00:00
// Time on target: caption
2012-04-15 10:09:54 +00:00
if ( TargetObject & & Cursor = = C4MC_Cursor_Select )
2009-10-16 21:07:43 +00:00
{
2012-02-25 20:56:11 +00:00
TimeOnTargetObject + + ;
if ( TimeOnTargetObject > = C4MC_Time_on_Target )
2009-10-16 21:07:43 +00:00
{
2012-04-15 10:09:54 +00:00
if ( TargetObject - > Category & C4D_MouseSelect )
2010-03-28 18:58:01 +00:00
{
2012-04-15 10:09:54 +00:00
// set caption
if ( ! KeepCaption )
2012-02-25 20:56:11 +00:00
{
2012-04-15 10:09:54 +00:00
C4String * tooltip = TargetObject - > GetPropertyStr ( P_Tooltip ) ;
if ( tooltip ) {
Caption = TargetObject - > GetPropertyStr ( P_Tooltip ) - > GetData ( ) ;
}
2012-02-25 20:56:11 +00:00
}
2012-04-15 10:09:54 +00:00
}
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
TimeOnTargetObject = 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
if ( OldTargetObject ! = TargetObject )
{
// 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 ;
if ( ! RightButtonDown ) DownTarget = NULL ;
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
{
C4Object * drag_image_obj ; C4ID drag_image_id ;
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 ) & &
DownTarget - > GetDragImage ( & drag_image_obj , & drag_image_id ) )
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 ;
else DragImageDef = C4Id2Def ( drag_image_id ) ;
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 ;
if ( ! LeftButtonDown ) DownTarget = NULL ;
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
{
2010-01-25 04:00:59 +00:00
//short iDelta = (short)(dwFlags >> 16);
2009-05-08 13:28:41 +00:00
// Normal wheel: control zoom
2010-03-28 18:58:01 +00:00
if ( ! ControlDown )
{
2009-12-31 17:20:45 +00:00
//if(iDelta > 0) Viewport->ChangeZoom(C4GFX_ZoomStep);
//if(iDelta < 0) Viewport->ChangeZoom(1.0f/C4GFX_ZoomStep);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Ctrl + Wheel: pass to player control (might be used for inventory or such)
else
2010-03-28 18:58:01 +00:00
{
2010-01-25 04:00:59 +00:00
// TODO
2009-05-28 00:14:54 +00:00
//if(iDelta > 0) Game.LocalPlayerControl(Player, COM_WheelUp);
//if(iDelta < 0) Game.LocalPlayerControl(Player, COM_WheelDown);
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
bool C4MouseControl : : IsValidMenu ( C4Menu * pMenu )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Local control fullscreen menu
if ( pMenu = = FullScreen . pMenu )
if ( pMenu - > IsActive ( ) )
2009-08-15 18:50:32 +00:00
return true ;
2009-05-08 13:28:41 +00:00
// Local control player menu
C4Player * pPlr ;
2010-01-25 04:00:59 +00:00
for ( int32_t cnt = 0 ; ( pPlr = : : Players . Get ( cnt ) ) ; cnt + + )
2009-05-08 13:28:41 +00:00
if ( pMenu = = & ( pPlr - > Menu ) )
if ( pMenu - > IsActive ( ) )
2009-08-15 18:50:32 +00:00
return true ;
2009-05-08 13:28:41 +00:00
// No match found
2009-08-15 18:50:32 +00:00
return false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
bool C4MouseControl : : SendControl ( int32_t iCom , int32_t iData )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Activate player menu / fullscreen main menu (local control)
if ( iCom = = COM_PlayerMenu )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( IsPassive ( ) & & FullScreen . Active )
FullScreen . ActivateMenuMain ( ) ;
else
pPlayer - > ActivateMenuMain ( ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Open chat
if ( iCom = = COM_Chat )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
C4ChatDlg : : ShowChat ( ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// other controls not valid in passive mode
2009-08-15 18:50:32 +00:00
if ( IsPassive ( ) ) return false ;
2009-05-08 13:28:41 +00:00
// Player control queue
2009-10-16 21:07:43 +00:00
Game . Input . Add ( CID_PlrControl , new C4ControlPlayerControl ( Player , iCom , iData ) ) ;
2009-05-08 13:28:41 +00:00
// Done
2009-08-15 18:50:32 +00:00
return true ;
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 ;
2011-12-25 18:16:50 +00:00
DragImageObject = NULL ;
DragImageDef = NULL ;
2009-12-30 19:16:32 +00:00
C4Object * DragObject = this - > DragObject ;
this - > DragObject = NULL ;
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 ) )
DropObject = NULL ;
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 : : SendCommand ( int32_t iCommand , int32_t iX , int32_t iY , C4Object * pTarget , C4Object * pTarget2 , int32_t iData , int32_t iAddMode )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// no commands in passive mode
if ( IsPassive ( ) ) return ;
// no commands if player is eliminated or doesn't exist any more
2009-06-12 23:09:32 +00:00
C4Player * pPlr = : : Players . Get ( Player ) ;
2009-05-08 13:28:41 +00:00
if ( ! pPlr | | pPlr - > Eliminated ) return ;
// User add multiple command mode
if ( ShiftDown ) iAddMode | = C4P_Command_Append ;
// Command to control queue
2009-10-16 21:07:43 +00:00
Game . Input . Add ( CID_PlrCommand , new C4ControlPlayerCommand ( Player , iCommand , iX , iY , pTarget , pTarget2 , iData , iAddMode ) ) ;
2010-03-28 18:58:01 +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
if ( ( pPlayer - > fFogOfWar & & ! pPlayer - > FoWIsVisible ( int32_t ( GameX ) , int32_t ( GameY ) ) ) | | GameX < 0 | | GameY < 0 | | int32_t ( GameX ) > = GBackWdt | | int32_t ( GameY ) > = GBackHgt )
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
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 ) ;
2009-05-08 13:28:41 +00:00
if ( ! pObj ) return NULL ;
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
Viewport - > ViewX = Viewport - > ViewX + iX ;
Viewport - > ViewY = Viewport - > ViewY + iY ;
Viewport - > UpdateViewPosition ( ) ;
}
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
bool C4MouseControl : : GetLastGUIPos ( int32_t * x_out , int32_t * y_out ) const
{
// safety
if ( ! Active | | ! fMouseOwned ) return false ;
// OK; assign last known pos
* x_out = GuiX ; * y_out = GuiY ;
return true ;
2010-09-24 17:52:20 +00:00
}