Add infos into target window
[ryzomcore.git] / ryzom / client / src / r2 / tool_maintained_action.cpp
blob7ed103e3510d386cdd55f664019b13f1a8f7dfde
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdpch.h"
22 #include "tool_maintained_action.h"
23 #include "editor.h"
24 #include "../interface_v3/interface_manager.h"
26 #ifdef DEBUG_NEW
27 #define new DEBUG_NEW
28 #endif
30 namespace R2
33 // ***************************************************************
34 CToolMaintainedAction::CToolMaintainedAction()
36 _State = Idle;
37 _LeftButtonDown = false;
38 _RightButtonDown = true;
39 _PreviousToolClickEnd = false;
40 _LostFocusRecover = false;
43 // ***************************************************************
44 CToolMaintainedAction::~CToolMaintainedAction()
46 // getEditor().setFocusedInstance(NULL);
49 // ***************************************************************
50 void CToolMaintainedAction::cancel()
52 //H_AUTO(R2_CToolMaintainedAction_cancel)
53 if (_State == Action)
55 if (_TargetInstance)
57 cancelAction(*_TargetInstance);
60 releaseMouse();
61 _State = Idle;
65 // ***************************************************************
66 bool CToolMaintainedAction::onMouseLeftButtonDown()
68 //H_AUTO(R2_CToolMaintainedAction_onMouseLeftButtonDown)
69 CTool::TSmartPtr holdThis(this); // prevent deletion by son (if they set another tool)
70 // TODO nico : find a more general system than this, because
71 if (_State == Action) return true; // may happen if focus was lost
72 if (_State == Canceling)
74 releaseMouse();
75 _State = Idle; // better for ergonomy (of if focus was lost, in which case we can't detect the button was up)
77 CInstance *instance = getEditor().getFocusedInstance();
78 if (!instance) return false;
79 _LeftButtonDown = true;
80 //if (isValidInstanceForAction(*focusedInstance) return false;
81 getEditor().setSelectedInstance(instance);
82 if (!isActionPossibleOn(*instance))
84 _State = ActionNotPossible;
86 else
88 captureMouse();
89 _TargetInstance = instance;
90 beginAction(*instance);
91 _State = Action;
93 return true;
96 // ***************************************************************
97 bool CToolMaintainedAction::onMouseLeftButtonUp()
99 //H_AUTO(R2_CToolMaintainedAction_onMouseLeftButtonUp)
100 bool mouseCaptured = isMouseCaptured();
101 if (mouseCaptured)
103 releaseMouse();
105 if (_State == Idle)
107 // NB : we need to release the mouse here and signal the event as handled, because a previous tool such as
108 // CToolDrawPrim terminates on a 'leftMouseDown' event then switch to the default 'SelectMove' tool
109 // Not handling the event would trigger 'the mouseLeftClick' event which result in the default action 'unselect'
110 return mouseCaptured;
112 if (_State == ActionNotPossible)
114 _State = Idle;
115 return true;
117 _LeftButtonDown = false;
118 if (_State == Canceling)
120 if (!_RightButtonDown) // both buttons must be released before mouse is released
122 releaseMouse();
123 _State = Idle;
125 return true;
127 // from now the event is considered handled
128 _State = Idle;
129 if (!_TargetInstance) return true;
130 commitAction(*_TargetInstance);
131 return true;
134 // ***************************************************************
135 bool CToolMaintainedAction::onMouseRightButtonDown()
137 //H_AUTO(R2_CToolMaintainedAction_onMouseRightButtonDown)
138 if (_State == Canceling)
140 releaseMouse();
142 _State = Idle; // better for ergonomy (if focus was lost, in which case we can't detect the button was up)
144 _LeftButtonDown = true;
145 if (_State != Action)
147 return defaultRightButtonDownHandling();
149 if (_TargetInstance)
151 cancelAction(*_TargetInstance);
153 // Enter 'canceling' state : both button must be released before any other action can be done
154 _State = Canceling;
155 captureMouse();
156 return true;
159 // ***************************************************************
160 bool CToolMaintainedAction::onMouseRightButtonUp()
162 //H_AUTO(R2_CToolMaintainedAction_onMouseRightButtonUp)
163 _LeftButtonDown = false;
164 if (_State == Canceling)
166 if (!_LeftButtonDown) // both buttons must be released before before mouse is released
168 releaseMouse();
169 _State = Idle;
171 return true;
173 return false;
176 // ***************************************************************
177 bool CToolMaintainedAction::onMouseLeftButtonClicked()
179 //H_AUTO(R2_CToolMaintainedAction_onMouseLeftButtonClicked)
180 // if this message reach us, then the user clicked somewhere in the view, so cancel the current
181 // selection
182 CGroupMap *gm = CTool::isMouseOnWorldMap();
183 if (gm)
185 if (CWidgetManager::getInstance()->getCapturePointerLeft())
187 return false;
190 if (!_PreviousToolClickEnd)
192 getEditor().setSelectedInstance(NULL);
194 _PreviousToolClickEnd = false;
195 // special case for the minimap :
196 // we say that the click has been handled only if mouse was already captured by the map
197 return true;
200 // ***************************************************************
201 const char *CToolMaintainedAction::getDefaultCursor() const
203 //H_AUTO(R2_CToolMaintainedAction_getDefaultCursor)
204 return DEFAULT_CURSOR;
207 // ***************************************************************
208 const char *CToolMaintainedAction::getPickCursor() const
210 //H_AUTO(R2_CToolMaintainedAction_getPickCursor)
211 return "curs_pick.tga";
214 // ***************************************************************
215 void CToolMaintainedAction::updateBeforeRender()
217 //H_AUTO(R2_CToolMaintainedAction_updateBeforeRender)
218 // no-op
222 // ***************************************************************
223 void CToolMaintainedAction::onFocusGained()
225 if (_State == Idle)
227 updateFocusedInstance(); // if alt-tab was used then udpdate focused instanceright now
228 _LostFocusRecover = true;
232 // ***************************************************************
233 bool CToolMaintainedAction::onMouseMove()
235 if (_LostFocusRecover)
237 // If app focus was retrieved by a click in the scene, then
238 // must update focused instance as a MouseMove is received, so that next 'mouse down' event can be on the right entity.
239 // events sequence is :
240 // - focus gained
241 // - mouse move
242 // - possibly 'mouse down' <- here focused instance needs to be good, hence the following code !
244 updateFocusedInstance();
245 _LostFocusRecover = false;
247 return false;
250 // ***************************************************************
251 void CToolMaintainedAction::updateFocusedInstance()
253 //handleMouseOverInstance(DEFAULT_CURSOR, , getCursorForPossibleAction());
254 setMouseCursor(getDefaultCursor());
255 CInstance *instanceUnder = checkInstanceUnderMouse();
256 if (!instanceUnder)
258 getEditor().setFocusedInstance(NULL);
259 return;
262 getEditor().setFocusedInstance(instanceUnder);
263 if (instanceUnder != getEditor().getSelectedInstance())
265 setMouseCursor(isMouseOnWorldMap() ? "curs_default.tga" : getPickCursor()); // do not show the selection circle on the
266 // map because it may cover other objects around
268 else
270 // if on the UI, just display the default cursor
271 if (isMouseOnUI())
273 setMouseCursor("curs_default.tga");
275 else
277 if (isActionPossibleOn(*instanceUnder))
279 // indicate that the user can move the instance
280 setMouseCursor(getCursorForPossibleAction());
282 else
284 setMouseCursor("curs_stop.tga");
290 // ***************************************************************
291 void CToolMaintainedAction::updateAfterRender()
293 //H_AUTO(R2_CToolMaintainedAction_updateAfterRender)
294 switch(_State)
296 case Action:
298 if (_TargetInstance)
300 updateAction(*_TargetInstance);
303 break;
304 case ActionNotPossible:
305 case Idle:
307 updateFocusedInstance();
309 break;
310 case Canceling:
311 setMouseCursor(DEFAULT_CURSOR); //\TODO nico Maybe a special cursor here would be more informative ?
312 break;
316 // ***************************************************************
317 bool CToolMaintainedAction::getPreviousToolClickEndFlag(bool clear /*=true*/)
319 //H_AUTO(R2_CToolMaintainedAction_getPreviousToolClickEndFlag)
320 bool flag = _PreviousToolClickEnd;
321 if (clear)
323 _PreviousToolClickEnd = false;
325 return flag;
330 } // R2