2009-05-08 13:28:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2009-06-05 13:41:20 +00:00
* Copyright ( c ) 1998 - 2000 , 2003 - 2004 Matthes Bender
* Copyright ( c ) 2001 - 2003 , 2005 - 2007 Sven Eberhardt
* Copyright ( c ) 2002 , 2004 Peter Wortmann
* Copyright ( c ) 2005 - 2006 , 2008 G ü nther Brammer
* Copyright ( c ) 2006 Armin Burgmeier
2009-05-08 13:28:41 +00:00
* Copyright ( c ) 2001 - 2009 , RedWolf Design GmbH , http : //www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk .
*
* Permission to use , copy , modify , and / or distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
* See isc_license . txt for full license and disclaimer .
*
* " Clonk " is a registered trademark of Matthes Bender .
* See clonk_trademark_license . txt for full license .
*/
/* Mouse input */
# include <C4Include.h>
# include <C4MouseControl.h>
# 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>
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_Selecting = 1 ,
C4MC_Drag_Moving = 2 ,
//C4MC_Drag_Menu = 3,
//C4MC_Drag_MenuScroll = 4,
C4MC_Drag_Construct = 5 ,
C4MC_Drag_Script = 6 ,
C4MC_Drag_Unhandled = 7 ,
2010-03-28 18:58:01 +00:00
2010-04-18 08:51:50 +00:00
C4MC_Selecting_Unknown = 0 ;
2010-03-28 18:58:01 +00:00
const int32_t C4MC_Cursor_Region = 0 ,
2010-04-18 08:51:50 +00:00
C4MC_Cursor_Crosshair = 1 ,
C4MC_Cursor_Enter = 2 ,
C4MC_Cursor_Grab = 3 ,
C4MC_Cursor_Chop = 4 ,
C4MC_Cursor_Dig = 5 ,
C4MC_Cursor_Build = 6 ,
C4MC_Cursor_Select = 7 ,
C4MC_Cursor_Object = 8 ,
C4MC_Cursor_Ungrab = 9 ,
C4MC_Cursor_Up = 10 ,
C4MC_Cursor_Down = 11 ,
C4MC_Cursor_Left = 12 ,
C4MC_Cursor_Right = 13 ,
C4MC_Cursor_UpLeft = 14 ,
C4MC_Cursor_UpRight = 15 ,
C4MC_Cursor_DownLeft = 16 ,
C4MC_Cursor_DownRight = 17 ,
C4MC_Cursor_JumpLeft = 18 ,
C4MC_Cursor_JumpRight = 19 ,
C4MC_Cursor_Drop = 20 ,
C4MC_Cursor_ThrowRight = 21 ,
C4MC_Cursor_Put = 22 ,
//C4MC_Cursor_DragMenu = 23,
C4MC_Cursor_Vehicle = 24 ,
C4MC_Cursor_VehiclePut = 25 ,
C4MC_Cursor_ThrowLeft = 26 ,
C4MC_Cursor_DragDrop = 26 ,
C4MC_Cursor_Point = 27 ,
C4MC_Cursor_DigObject = 28 ,
C4MC_Cursor_Help = 29 ,
C4MC_Cursor_DigMaterial = 30 ,
C4MC_Cursor_Add = 31 ,
C4MC_Cursor_Construct = 32 ,
C4MC_Cursor_Attack = 33 ,
C4MC_Cursor_Nothing = 34 ;
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 ;
Cursor = DownCursor = 0 ;
Caption . Clear ( ) ;
IsHelpCaption = false ;
CaptionBottomY = 0 ;
VpX = VpY = 0 ;
DownX = DownY = DownOffsetX = DownOffsetY = 0 ;
ViewX = ViewY = 0 ;
GuiX = GuiY = GameX = GameY = 0 ;
ShowPointX = ShowPointY = - 1 ;
LeftButtonDown = RightButtonDown = false ;
LeftDoubleIgnoreUp = false ;
ButtonDownOnSelection = false ;
Visible = true ;
InitCentered = false ;
Help = 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 ;
Drag = C4MC_Drag_None ; DragSelecting = C4MC_Selecting_Unknown ;
Selection . Default ( ) ;
TargetObject = DownTarget = NULL ;
TimeOnTargetObject = 0 ;
ControlDown = false ;
ShiftDown = false ;
Scrolling = false ;
ScrollSpeed = 10 ;
TargetRegion = NULL ;
DownRegion . Default ( ) ;
DragImage . Default ( ) ;
DragImagePhase = 0 ;
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 ;
if ( Application . IsControlDown ( ) ) wKeyState | = MK_CONTROL ;
if ( Application . IsShiftDown ( ) ) wKeyState | = MK_SHIFT ;
Move ( C4MC_Button_None , VpX , VpY , wKeyState ) ;
}
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 ;
DragImage . Default ( ) ;
}
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
# ifdef _WIN32
// fullscreen only
if ( ! Application . isFullScreen ) return ;
// application or mouse control not active? remove any clips
2009-06-05 16:53:56 +00:00
if ( ! Active | | ! Application . Active | | ( : : pGUI & & : : pGUI - > HasMouseFocus ( ) ) ) { ClipCursor ( NULL ) ; return ; }
2009-05-08 13:28:41 +00:00
// get controlled viewport
2009-06-05 15:14:20 +00:00
C4Viewport * pVP = : : GraphicsSystem . 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
2009-06-05 16:53:56 +00:00
if ( : : pGUI )
: : 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
{
2009-05-08 13:28:41 +00:00
// Active
if ( ! Active | | ! fMouseOwned ) return ;
// Execute caption
if ( KeepCaption ) KeepCaption - - ; else { Caption . Clear ( ) ; IsHelpCaption = false ; CaptionBottomY = 0 ; }
// 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
2009-06-05 15:14:20 +00:00
if ( ! ( Viewport = : : GraphicsSystem . 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
# ifdef _WIN32
if ( ! InitCentered | | fCenter )
{
iX = Viewport - > ViewWdt / 2 ;
iY = Viewport - > ViewHgt / 2 ;
if ( Application . isFullScreen )
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 ;
if ( Application . isFullScreen )
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 ;
GuiX = float ( VpX ) / C4GUI : : GetZoom ( ) ; GuiY = float ( VpY ) / C4GUI : : GetZoom ( ) ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
UpdateTargetRegion ( ) ;
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 ;
GuiX = float ( VpX ) / C4GUI : : GetZoom ( ) ; GuiY = float ( VpY ) / C4GUI : : GetZoom ( ) ;
// Control state
ControlDown = false ; if ( dwKeyFlags & MK_CONTROL ) ControlDown = true ;
ShiftDown = false ; if ( dwKeyFlags & MK_SHIFT ) ShiftDown = true ;
// Target region
UpdateTargetRegion ( ) ;
// Scrolling
UpdateScrolling ( ) ;
// Fog of war
UpdateFogOfWar ( ) ;
// Blocked by fog of war: evaluate button up, dragging and region controls only
if ( FogOfWar & & Drag = = C4MC_Drag_None & & ! TargetRegion )
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_Selecting : DragSelect ( ) ; break ;
case C4MC_Drag_Moving : DragMoving ( ) ; break ;
case C4MC_Drag_Construct : DragConstruct ( ) ; 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
// 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 ( ! TargetRegion & & ! TargetObject )
// safety (can't really happen in !IsPassive, but w/e
if ( pPlayer & & pPlayer - > ControlSet )
{
if ( pPlayer - > ControlSet - > IsMouseControlAssigned ( iButton ) )
{
2009-12-31 17:20:45 +00:00
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 , ControlDown , ShiftDown , Application . IsAltDown ( ) , 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 ;
2009-12-31 17:20:45 +00:00
pPlayer - > Control . DoMouseInput ( 0 /* only 1 mouse supported so far */ , C4MC_Button_None , GameX , GameY , GuiX , GuiY , ControlDown , ShiftDown , Application . IsAltDown ( ) , 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 ;
lpDDraw - > GetZoom ( & GuiZoom ) ;
// 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
//------------------------------------------------------------------------------------------
2010-04-18 08:51:50 +00:00
case C4MC_Drag_None : case C4MC_Drag_Moving : case C4MC_Drag_Construct : 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
}
// Add mark
bool fAddMark ; fAddMark = false ;
if ( ShiftDown )
if ( ( Cursor ! = C4MC_Cursor_Region ) & & ( Cursor ! = C4MC_Cursor_Select ) //&& (Cursor!=C4MC_Cursor_DragMenu)
& & ( Cursor ! = C4MC_Cursor_JumpLeft ) & & ( Cursor ! = C4MC_Cursor_JumpRight ) )
if ( ! IsPassive ( ) )
fAddMark = true ;
// Drag image
if ( DragImage . Surface )
{
// 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
{
2010-03-28 18:58:01 +00:00
lpDDraw - > SetZoom ( GameZoom ) ;
XDraw = GameX ; YDraw = GameY ;
ZoomDraw = 1.0f ;
// for drag construct: draw rounded to game pixels, because construction site will be placed at rounded game pixel positions
if ( Drag = = C4MC_Drag_Construct ) { XDraw = floor ( XDraw ) ; YDraw = floor ( YDraw ) ; }
2009-10-16 21:07:43 +00:00
}
2010-03-28 18:58:01 +00:00
else
{
ZoomDraw = 64.0f / DragImage . Wdt ;
XDraw = GuiX ; YDraw = GuiY ;
}
// draw in special modulation mode
lpDDraw - > SetBlitMode ( C4GFXBLIT_MOD2 ) ;
// draw DragImage in red or green, according to the phase to be used
iOffsetX = int ( ZoomDraw * DragImage . Wdt / 2 ) ;
if ( Drag = = C4MC_Drag_Construct )
iOffsetY = int ( ZoomDraw * DragImage . Hgt ) ;
else
iOffsetY = int ( ZoomDraw * DragImage . Hgt / 2 ) ;
lpDDraw - > ActivateBlitModulation ( ( Drag = = C4MC_Drag_Script ) ? 0x7fffffff : ( DragImagePhase ? 0x8f7f0000 : 0x1f007f00 ) ) ;
lpDDraw - > Blit ( DragImage . Surface ,
float ( DragImage . X ) , float ( DragImage . Y ) , float ( DragImage . Wdt ) , float ( DragImage . Hgt ) ,
cgo . Surface ,
XDraw + cgo . X - iOffsetX , YDraw + cgo . Y - iOffsetY , float ( DragImage . Wdt ) * ZoomDraw , float ( DragImage . Hgt ) * ZoomDraw , true ) ;
// reset color
lpDDraw - > DeactivateBlitModulation ( ) ;
lpDDraw - > SetBlitMode ( 0 ) ;
if ( fIsGameZoom ) lpDDraw - > SetZoom ( GuiZoom ) ;
// reset cursor hotspot offset for script drawing
iOffsetX = GfxR - > fctMouseCursor . Wdt / 2 ;
iOffsetY = GfxR - > fctMouseCursor . Hgt / 2 ;
}
// Cursor
if ( ! DragImage . Surface | | ( Drag = = C4MC_Drag_Script ) )
GfxR - > fctMouseCursor . Draw ( cgo . Surface , cgo . X + GuiX - iOffsetX , cgo . Y + GuiY - iOffsetY , Cursor ) ;
// Point
if ( ( ShowPointX ! = - 1 ) & & ( ShowPointY ! = - 1 ) )
GfxR - > fctMouseCursor . Draw ( cgo . Surface ,
int32_t ( cgo . X + ( ShowPointX - cgo . TargetX ) * GameZoom . Zoom / GuiZoom . Zoom - GfxR - > fctMouseCursor . Wdt / 2 ) ,
int32_t ( cgo . Y + ( ShowPointY - cgo . TargetY ) * GameZoom . Zoom / GuiZoom . Zoom - GfxR - > fctMouseCursor . Hgt / 2 ) ,
C4MC_Cursor_Point ) ;
// Add mark
if ( fAddMark )
GfxR - > fctMouseCursor . Draw ( cgo . Surface ,
int32_t ( cgo . X + GuiX - iOffsetX + 8 ) ,
int32_t ( cgo . Y + GuiY - iOffsetY + 8 ) ,
C4MC_Cursor_Add ) ;
break ;
2009-05-08 13:28:41 +00:00
//------------------------------------------------------------------------------------------
2010-03-28 18:58:01 +00:00
case C4MC_Drag_Selecting :
// Draw frame
2010-06-28 23:02:16 +00:00
Application . DDraw - > DrawFrameDw ( cgo . Surface ,
2010-03-28 18:58:01 +00:00
int32_t ( cgo . X + GuiX ) ,
int32_t ( cgo . Y + GuiY ) ,
int32_t ( cgo . X + ( DownX - cgo . TargetX ) * GameZoom . Zoom / GuiZoom . Zoom ) ,
int32_t ( cgo . Y + ( DownY - cgo . TargetY ) * GameZoom . Zoom / GuiZoom . Zoom ) ,
2010-06-28 23:02:16 +00:00
C4RGB ( 0xca , 0 , 0 ) ) ;
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
if ( Caption )
2009-10-16 21:07:43 +00:00
{
2009-06-05 16:53:56 +00:00
if ( IsHelpCaption & & : : pGUI )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// Help: Tooltip style
C4TargetFacet cgoTip ; cgoTip = static_cast < const C4Facet & > ( cgo ) ;
C4GUI : : Screen : : DrawToolTip ( Caption . getData ( ) , cgoTip , cgo . X + GuiX , cgo . Y + GuiY ) ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
else
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// Otherwise red mouse control style
int32_t iWdt , iHgt ;
2009-06-05 15:19:15 +00:00
: : GraphicsResource . FontRegular . GetTextExtent ( Caption . getData ( ) , iWdt , iHgt , true ) ;
Application . DDraw - > TextOut ( Caption . getData ( ) , : : GraphicsResource . FontRegular , 1.0 ,
2010-03-28 18:58:01 +00:00
cgo . Surface ,
float ( cgo . X ) + BoundBy < float > ( GuiX , float ( iWdt ) / 2 + 1 , float ( cgo . Wdt ) - iWdt / 2 - 1 ) ,
float ( cgo . Y ) + Min < float > ( CaptionBottomY ? float ( CaptionBottomY - iHgt - 1 ) : GuiY + 13 , float ( cgo . Hgt - iHgt ) ) ,
0xfaFF0000 , ACenter ) ;
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
{
2009-05-08 13:28:41 +00:00
int32_t iLastCursor = Cursor ;
// Scrolling: no other target
if ( Scrolling ) { TargetObject = NULL ; return ; }
// On target region
if ( TargetRegion )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
TargetObject = NULL ;
if ( Help ) Cursor = C4MC_Cursor_Help ;
return ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
// Target object
2009-10-16 21:07:43 +00:00
TargetObject = GetTargetObject ( ) ;
2009-05-08 13:28:41 +00:00
if ( TargetObject & & FogOfWar & & ! ( TargetObject - > Category & C4D_IgnoreFoW ) ) TargetObject = NULL ;
2009-10-16 21:07:43 +00:00
// Movement
if ( ! FogOfWar & & ! IsPassive ( ) ) Cursor = C4MC_Cursor_Crosshair ;
2009-05-08 13:28:41 +00:00
// Target action
2009-10-16 21:07:43 +00:00
if ( TargetObject & & ! IsPassive ( ) )
{
2009-05-08 13:28:41 +00:00
// default cursor for object; also set if not in FoW
Cursor = C4MC_Cursor_Crosshair ;
// select custom region
if ( TargetObject - > Category & C4D_MouseSelect )
Cursor = C4MC_Cursor_Select ;
2009-10-16 21:07:43 +00:00
}
2010-03-28 18:58:01 +00:00
2009-05-08 13:28:41 +00:00
// Help
if ( Help )
Cursor = C4MC_Cursor_Help ;
// passive cursor
else if ( IsPassive ( ) )
Cursor = C4MC_Cursor_Region ;
2010-03-28 18:58:01 +00:00
2009-05-08 13:28:41 +00:00
// Time on target: caption
if ( Cursor = = iLastCursor )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
TimeOnTargetObject + + ;
if ( TimeOnTargetObject > = C4MC_Time_on_Target )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
const char * idCaption = 0 ;
const char * szName = " " ;
bool fDouble = false ;
if ( TargetObject ) szName = TargetObject - > GetName ( ) ;
// Target caption by cursor
switch ( Cursor )
2009-10-16 21:07:43 +00:00
{
2010-03-28 18:58:01 +00:00
case C4MC_Cursor_Select : idCaption = " IDS_CON_SELECT " ; break ;
case C4MC_Cursor_Help : idCaption = " IDS_CON_NAME " ; break ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
// Set caption
if ( idCaption ) if ( ! KeepCaption )
2010-03-28 18:58:01 +00:00
{
// Caption by cursor
Caption . Format ( LoadResStr ( idCaption ) , szName ) ;
if ( fDouble ) { Caption . AppendChar ( ' | ' ) ; Caption . Append ( LoadResStr ( " IDS_CON_DOUBLECLICK " ) ) ; }
IsHelpCaption = false ;
}
2009-05-08 13:28:41 +00:00
}
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
else
TimeOnTargetObject = 0 ;
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-05-08 13:28:41 +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 ;
// No scrolling if on region
if ( TargetRegion ) return ;
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 )
{ Cursor = C4MC_Cursor_Left ; ScrollView ( - ScrollSpeed , 0 , Viewport - > ViewWdt , Viewport - > ViewHgt ) ; Scrolling = true ; }
if ( VpY = = 0 )
{ Cursor = C4MC_Cursor_Up ; ScrollView ( 0 , - ScrollSpeed , Viewport - > ViewWdt , Viewport - > ViewHgt ) ; Scrolling = true ; }
if ( VpX = = Viewport - > ViewWdt - 1 )
{ Cursor = C4MC_Cursor_Right ; ScrollView ( + ScrollSpeed , 0 , Viewport - > ViewWdt , Viewport - > ViewHgt ) ; Scrolling = true ; }
if ( VpY = = Viewport - > ViewHgt - 1 )
{ Cursor = C4MC_Cursor_Down ; ScrollView ( 0 , + ScrollSpeed , Viewport - > ViewWdt , Viewport - > ViewHgt ) ; Scrolling = true ; }
// 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 : : UpdateTargetRegion ( )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// Assume no region
TargetRegion = NULL ;
// Find region
if ( ! ( TargetRegion = Viewport - > Regions . Find ( GuiX , GuiY ) ) ) return ;
// Region found: no target object
TargetObject = NULL ;
// Cursor
Cursor = C4MC_Cursor_Region ;
// Stop drag selecting (reset down cursor, too)
if ( Drag = = C4MC_Drag_Selecting )
{ Drag = C4MC_Drag_None ; DownCursor = C4MC_Cursor_Nothing ; }
// Caption
Caption . Copy ( TargetRegion - > Caption ) ;
IsHelpCaption = false ;
CaptionBottomY = TargetRegion - > Y ; KeepCaption = 0 ;
// Help region caption by region target object; not in menu, because this would be the cursor object
if ( Help )
if ( TargetRegion - > Target /*&& Cursor!=C4MC_Cursor_DragMenu*/ )
2009-10-16 21:07:43 +00:00
{
2010-08-23 13:20:27 +00:00
//if (TargetRegion->Target->Def->GetDesc())
// Caption.Format("%s: %s",TargetRegion->Target->GetName(), TargetRegion->Target->Def->GetDesc());
//else
2009-05-08 13:28:41 +00:00
Caption . Copy ( TargetRegion - > Target - > GetName ( ) ) ;
IsHelpCaption = true ;
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
// MoveOverCom (on region change)
static int32_t iLastRegionX , iLastRegionY ;
if ( TargetRegion - > MoveOverCom )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
if ( ( TargetRegion - > X ! = iLastRegionX ) | | ( TargetRegion - > Y ! = iLastRegionY ) )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
iLastRegionX = TargetRegion - > X ; iLastRegionY = TargetRegion - > Y ;
// Control queue
Game . Input . Add ( CID_PlrControl ,
2010-03-28 18:58:01 +00:00
new C4ControlPlayerControl ( Player , TargetRegion - > MoveOverCom , TargetRegion - > Data ) ) ;
2009-05-08 13:28:41 +00:00
}
}
2009-10-16 21:07:43 +00:00
else
2009-05-08 13:28:41 +00:00
{
2009-10-16 21:07:43 +00:00
iLastRegionX = iLastRegionY = - 1 ;
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 : : 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 ;
DownCursor = Cursor ;
DownTarget = TargetObject ;
DownRegion . Default ( ) ;
if ( TargetRegion )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
DownRegion = ( * TargetRegion ) ;
DownTarget = TargetRegion - > Target ;
DownOffsetX = TargetRegion - > X - GuiX ; DownOffsetY = TargetRegion - > Y - GuiY ;
}
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : DragSelect ( )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// don't select into FoW - simply don't update selection
if ( FogOfWar ) return ;
switch ( DragSelecting )
2009-10-16 21:07:43 +00:00
{
2010-03-28 18:58:01 +00:00
case C4MC_Selecting_Unknown :
// Determine selection type
// No selection in engine right now...
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
void C4MouseControl : : LeftUp ( )
2009-10-16 21:07:43 +00:00
{
2009-05-08 13:28:41 +00:00
// Update status flag
LeftButtonDown = false ;
// Ignore left up after double click
if ( LeftDoubleIgnoreUp ) { LeftDoubleIgnoreUp = false ; return ; }
// Evaluate by drag status
switch ( Drag )
2009-10-16 21:07:43 +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 : LeftUpDragNone ( ) ; break ;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-03-28 18:58:01 +00:00
case C4MC_Drag_Selecting : ButtonUpDragSelecting ( ) ; break ;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-03-28 18:58:01 +00:00
case C4MC_Drag_Moving : ButtonUpDragMoving ( ) ; break ;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-03-28 18:58:01 +00:00
case C4MC_Drag_Construct : ButtonUpDragConstruct ( ) ; 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
}
2009-10-16 21:07:43 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : DragMoving ( )
2009-12-30 19:16:32 +00:00
{
2009-05-08 13:28:41 +00:00
ShowPointX = ShowPointY = - 1 ;
// do not drag objects into FoW
if ( FogOfWar ) { Cursor = C4MC_Cursor_Nothing ; return ; }
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
{
2009-05-08 13:28:41 +00:00
// Holding left down
if ( LeftButtonDown )
2009-12-30 19:16:32 +00:00
{
2009-05-08 13:28:41 +00:00
switch ( Cursor )
2009-12-30 19:16:32 +00:00
{
2009-05-08 13:28:41 +00:00
// Hold down on region
2010-03-28 18:58:01 +00:00
case C4MC_Cursor_Region :
if ( ! : : Game . iTick5 )
if ( DownRegion . HoldCom )
SendControl ( DownRegion . HoldCom ) ;
break ;
2009-05-08 13:28:41 +00:00
}
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
{
2009-05-08 13:28:41 +00:00
// don't begin dragging from FoW; unless it's a menu
if ( FogOfWar & & DownCursor ! = C4MC_Cursor_Region ) return ;
2009-12-30 19:16:32 +00:00
bool fAllowDrag = true ;
2009-05-08 13:28:41 +00:00
switch ( DownCursor )
2009-12-30 19:16:32 +00:00
{
2010-03-28 18:58:01 +00:00
/*
2009-05-08 13:28:41 +00:00
// Drag start selecting in landscape
2009-10-16 21:07:43 +00:00
case C4MC_Cursor_Crosshair :
2010-03-28 18:58:01 +00:00
Selection . Clear ( ) ;
Drag = C4MC_Drag_Selecting ; DragSelecting = C4MC_Selecting_Unknown ;
break ;
*/
2009-05-08 13:28:41 +00:00
// Help: no dragging
2010-03-28 18:58:01 +00:00
case C4MC_Cursor_Help :
fAllowDrag = false ;
break ;
2009-12-30 19:16:32 +00:00
}
// check if target object allows scripted dragging
2010-04-18 08:51:50 +00:00
if ( fAllowDrag & & TargetObject )
2009-12-30 19:16:32 +00:00
{
C4Object * drag_image_obj ; C4ID drag_image_id ;
if ( TargetObject - > GetDragImage ( & drag_image_obj , & drag_image_id ) )
{
Drag = C4MC_Drag_Script ;
2009-12-31 14:50:42 +00:00
CreateDragImage ( drag_image_id , drag_image_obj , true ) ;
2009-12-30 19:16:32 +00:00
DragObject = TargetObject ;
DragImagePhase = 0 ;
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 ;
DownCursor = Cursor ;
DownTarget = TargetObject ;
DownRegion . Default ( ) ;
if ( TargetRegion )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
DownRegion = ( * TargetRegion ) ;
DownTarget = TargetRegion - > Target ;
DownOffsetX = TargetRegion - > X - GuiX ; DownOffsetY = TargetRegion - > Y - GuiY ;
}
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
// Update status flag
RightButtonDown = false ;
// 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_Selecting : ButtonUpDragSelecting ( ) ; break ;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-03-28 18:58:01 +00:00
case C4MC_Drag_Moving : ButtonUpDragMoving ( ) ; break ;
2009-05-08 13:28:41 +00:00
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010-03-28 18:58:01 +00:00
case C4MC_Drag_Construct : ButtonUpDragConstruct ( ) ; 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
}
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
// Help
if ( iCom = = COM_Help )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Help = true ;
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
// 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-31 14:50:42 +00:00
void C4MouseControl : : CreateDragImage ( C4ID id , C4Object * obj , bool fPicture )
2010-03-28 18:58:01 +00:00
{
2009-12-30 19:16:32 +00:00
// todo: real object drawing
if ( obj ) id = obj - > id ;
2009-05-08 13:28:41 +00:00
// Get definition
C4Def * pDef = C4Id2Def ( id ) ; if ( ! pDef ) return ;
// in newgfx, it's just the base image, drawn differently...
2009-12-31 14:50:42 +00:00
if ( pDef - > DragImagePicture | | fPicture )
2009-05-08 13:28:41 +00:00
DragImage . Set ( pDef - > Graphics . GetBitmap ( ) , pDef - > PictureRect . x , pDef - > PictureRect . y , pDef - > PictureRect . Wdt , pDef - > PictureRect . Hgt ) ;
else
DragImage = pDef - > GetMainFace ( & pDef - > Graphics ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : DragConstruct ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Cursor = C4MC_Cursor_Construct ;
// Check site
DragImagePhase = 1 ;
2009-04-12 12:04:28 +00:00
if ( ! FogOfWar & & ConstructionCheck ( C4Id2Def ( DragID ) , int32_t ( GameX ) , int32_t ( GameY ) ) ) DragImagePhase = 0 ;
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 ;
// todo: Phase to 1 if drag is not possible. Interface to determine valid drag/drop does not exist yet
DragImagePhase = 0 ;
}
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
{
2009-05-08 13:28:41 +00:00
// Region
2010-03-28 18:58:01 +00:00
case C4MC_Cursor_Region :
// Help click on region: ignore
if ( Help ) break ;
// Region com & data
SendControl ( DownRegion . Com , DownRegion . Data ) ;
break ;
2009-05-08 13:28:41 +00:00
// Selection
2010-03-28 18:58:01 +00:00
case C4MC_Cursor_Select :
// Object selection to control queue
if ( ! IsPassive ( ) ) Game . Input . Add ( CID_PlrSelect , new C4ControlPlayerSelect ( Player , Selection , false ) ) ;
break ;
2009-05-08 13:28:41 +00:00
// Help
2010-03-28 18:58:01 +00:00
case C4MC_Cursor_Help :
if ( DownTarget )
{
2010-08-23 13:20:27 +00:00
//if (DownTarget->Def->GetDesc())
// Caption.Format("%s: %s",DownTarget->GetName(), DownTarget->Def->GetDesc());
//else
2010-03-28 18:58:01 +00:00
Caption . Copy ( DownTarget - > GetName ( ) ) ;
KeepCaption = Caption . getLength ( ) / 2 ;
IsHelpCaption = true ;
}
break ;
2009-05-08 13:28:41 +00:00
// Nothing
2010-03-28 18:58:01 +00:00
case C4MC_Cursor_Nothing :
break ;
2009-10-17 15:53:26 +00:00
// Movement?
2010-03-28 18:58:01 +00:00
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
void C4MouseControl : : ButtonUpDragSelecting ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Finish drag
Drag = C4MC_Drag_None ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : ButtonUpDragMoving ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Finish drag
Drag = C4MC_Drag_None ;
// Clear selection
Selection . Clear ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : ButtonUpDragConstruct ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Finish drag
Drag = C4MC_Drag_None ;
DragImage . Default ( ) ;
// Command
if ( DragImagePhase = = 0 ) // if ConstructionCheck was okay (check again?)
2010-01-25 15:57:57 +00:00
SendCommand ( C4CMD_Construct , int32_t ( GameX ) , int32_t ( GameY ) , NULL , NULL , DragID . GetHandle ( ) ) ;
2009-05-08 13:28:41 +00:00
// Clear selection (necessary?)
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 ( )
{
// Finish drag
Drag = C4MC_Drag_None ;
DragImage . Default ( ) ;
2010-01-25 03:14:52 +00:00
DragID = C4ID : : None ;
2009-12-30 19:16:32 +00:00
// Determine drag+drop targets
UpdateCursorTarget ( ) ;
C4Object * DragObject = this - > DragObject ;
this - > DragObject = NULL ;
C4Object * DropObject = TargetObject ;
// drag object must exist; drop object is optional
if ( ! DragObject ) return ;
// 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
if ( DropObject )
Game . Input . Add ( CID_Script , new C4ControlScript (
2010-03-28 18:58:01 +00:00
FormatString ( " %s(%d,Object(%d),Object(%d)) " , PSF_MouseDragDrop , ( int ) Player , ( int ) ( DragObject - > Number ) , ( int ) ( DropObject - > Number ) ) . getData ( ) ) ) ;
2009-12-30 19:16:32 +00:00
else
Game . Input . Add ( CID_Script , new C4ControlScript (
2010-03-28 18:58:01 +00:00
FormatString ( " %s(%d,Object(%d),nil) " , PSF_MouseDragDrop , ( int ) Player , ( int ) ( DragObject - > Number ) ) . getData ( ) ) ) ;
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-05-08 13:28:41 +00:00
// Region: send control
if ( Cursor = = C4MC_Cursor_Region )
{ SendControl ( DownRegion . RightCom ) ; return ; }
2009-12-29 17:54:39 +00:00
// Alternative object selection
if ( Cursor = = C4MC_Cursor_Select & & ! IsPassive ( ) )
{ Game . Input . Add ( CID_PlrSelect , new C4ControlPlayerSelect ( Player , Selection , true ) ) ; }
2009-05-08 13:28:41 +00:00
// Help: end
if ( Help )
{ Help = false ; KeepCaption = 0 ; return ; }
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
if ( ! TargetRegion & & ! Scrolling & & ( ! TargetObject | | ! ( TargetObject - > Category & C4D_IgnoreFoW ) ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Cursor = C4MC_Cursor_Nothing ;
ShowPointX = ShowPointY = - 1 ;
// dragging will reset the cursor
}
}
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
2009-12-22 21:10:42 +00:00
C4Object * pObj = Game . FindVisObject ( ViewX , ViewY , Player , fctViewportGame , fctViewportGUI , GameX , GameY , Help ? C4D_All : 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
void C4MouseControl : : ScrollView ( int32_t iX , int32_t iY , int32_t ViewWdt , int32_t 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
{
2009-05-08 13:28:41 +00:00
// no selection drag; return true for object drag only
2010-04-18 08:51:50 +00:00
return Active & & ( Drag = = C4MC_Drag_Moving | | Drag = = C4MC_Drag_Construct | | Drag = = C4MC_Drag_Script ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MouseControl : : StartConstructionDrag ( C4ID id )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Drag = C4MC_Drag_Construct ;
DragID = id ;
2009-12-31 14:50:42 +00:00
CreateDragImage ( DragID , NULL , false ) ;
2009-05-08 13:28:41 +00:00
Selection . Clear ( ) ;
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 ;
}