1 // -*- C++ -*-
2 
3 /*
4  * GChemPaint library
5  * tool.h
6  *
7  * Copyright (C) 2001-2011 Jean Bréfort <jean.brefort@normalesup.org>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 3 of the
12  * License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
22  * USA
23  */
24 
25 #ifndef GCHEMPAINT_TOOL_H
26 #define GCHEMPAINT_TOOL_H
27 
28 #include <gcu/macros.h>
29 #include <gtk/gtk.h>
30 #include <libxml/tree.h>
31 #include <vector>
32 #include <set>
33 #include <string>
34 
35 namespace gcu {
36 	class Dialog;
37 	class Object;
38 	class UIManager;
39 }
40 
41 namespace gccv {
42 	class Item;
43 }
44 
45 /*!\file*/
46 namespace gcp {
47 
48 class Application;
49 class View;
50 class WidgetData;
51 class Operation;
52 
53 /*!\class Tool
54 Base clas for GChemPaint tools.
55 */
56 class Tool
57 {
58 public:
59 /*!
60 @param App the GChemPaint application.
61 @param Id the name of the tool.
62 
63 Constructs a new tool.
64 */
65 	Tool (gcp::Application *App, std::string Id);
66 /*!
67 The destructor.
68 */
69 	virtual ~Tool ();
70 
71 /*!
72 @param pView the view instance owning the event.
73 @param pObject the Object on which the click occured.
74 @param x the horizontal position of the mouse when the click occured.
75 @param y the vertical position of the mouse when the click occured.
76 @param state a bit-mask representing the state of the modifier keys (e.g. Control, Shift and Alt) and the pointer buttons. See GdkModifierType in GDK documentation.
77 
78 This method is called by the framework when the tool is active and a click occurs. It initialize
79 some members and then calls the virtual OnClicked() method.
80 It might be called to simulate a click in some instances (e.g. from a contextual menu handler).
81 
82 @return true if the mouse drag and button release evens are significative for this tool
83 in the current context, false otherwise. If true, a mouse move will fire the OnDrag method,
84 and a button release will result in an OnRelease call. If false, nothing happens for these
85 events.
86 */
87 	bool OnClicked (View* pView, gcu::Object* pObject, double x, double y, unsigned int state);
88 
89 /*!
90 @param x the horizontal position of the mouse when the event occured.
91 @param y the vertical position of the mouse when the event occured.
92 @param state a bit-mask representing the state of the modifier keys (e.g. Control, Shift and Alt) and the pointer buttons. See GdkModifierType in GDK documentation.
93 
94 This method is called by the framework when the tool is active, the first mouse button
95 is pressed and the mouse is moved.
96 */
97 	void OnDrag (double x, double y, unsigned int state);
98 /*!
99 @param pView the view instance owning the event.
100 @param pObject the Object on which the click occured.
101 @param x the horizontal position of the mouse when the event occured.
102 @param y the vertical position of the mouse when the event occured.
103 @param state a bit-mask representing the state of the modifier keys (e.g. Control, Shift and Alt) and the pointer buttons. See GdkModifierType in GDK documentation.
104 
105 This method is called by the framework when the tool is active, the first mouse button
106 is not pressed and the mouse is moved.
107 */
108 	void OnMotion (View* pView, gcu::Object* pObject, double x, double y, unsigned int state);
109 /*!
110 @param pView the view instance owning the event.
111 @param state a bit-mask representing the state of the modifier keys (e.g. Control, Shift and Alt) and the pointer buttons. See GdkModifierType in GDK documentation.
112 
113 This method is called by the framework when the tool is active and the mouse is moved
114 outside the current view.
115 */
116 	void OnLeaveNotify (View* pView, unsigned int state);
117 /*!
118 @param x the horizontal position of the mouse when the event occured.
119 @param y the vertical position of the mouse when the event occured.
120 @param state a bit-mask representing the state of the modifier keys (e.g. Control, Shift and Alt) and the pointer buttons. See GdkModifierType in GDK documentation.
121 
122 This method is called by the framework when the tool is active and the first mouse button
123 is released.
124 */
125 	void OnRelease (double x, double y, unsigned int state);
126 /*!
127 @param pView the view where the event occured.
128 @param pObject the object on which the event occured.
129 @param x the horizontal position of the mouse when the event occured.
130 @param y the vertical position of the mouse when the event occured.
131 @param UIManager the gcu::UIManager in use.
132 
133 This method is called by the framework when the tool is active and the right mouse button
134 is pressed. It is used to add tool specific menu items to the contextual menu.
135 It calls OnRightButtonClicked(gcu::UIManager*).
136 
137 @return true if at least one menu item was added, false otherwise.
138 */
139 	bool OnRightButtonClicked (View* pView, gcu::Object* pObject, double x, double y, gcu::UIManager *UIManager);
140 /*!
141 @param bState whether to activate or deactivate the tool.
142 
143 When \a bState is true, the tool is activated, otherwise it is deactivated.
144 Activate() or Deactivate() is called for this instance.
145 @return true on success, and false otherwise. Activation always succeeds.
146 */
147 	bool Activate (bool bState);
148 /*!
149 @return the tool name.
150 */
GetName()151 	std::string& GetName () {return name;}
152 /*!
153 @param UIManager the gcu::UIManager in use.
154 
155 Adds menu items to the contextual menu.
156 Default implementation do not add any menu item and returns false. Derived classes
157 for which menu items exist must override this method.
158 @return true if at least one menu item was added, false otherwise.
159 */
160 	virtual bool OnRightButtonClicked (gcu::UIManager *UIManager);
161 /*!
162 Virtual method called when the tool is activated.
163 This method should be overriden for all tools which need some initialization
164 when activated. Default does nothing.
165 */
166 	virtual void Activate ();
167 /*!
168 Virtual method called when the tool is deactivated.
169 This method should be overriden for all tools which need some cleaning
170 when deactivated. Default does nothing.
171 @return true on success, false otherwise.
172 */
173 	virtual bool Deactivate ();
174 /*!
175 @param code the state of the mofifier keys as given inthe state field or
176 some GdkEvent derived structures.
177 
178 Called by the framework when a modifier key has been pressed, updates
179 m_nState, and calls Tool::OnChangeState ().
180 */
OnKeyPressed(unsigned int code)181 	void OnKeyPressed (unsigned int code) {m_nState |= code; OnChangeState ();}
182 /*!
183 @param code the state of the mofifier keys as given inthe state field or
184 some GdkEvent derived structures.
185 
186 Called by the framework when a modifier key has been released, updates
187 m_nState, and calls Tool::OnChangeState ().
188 */
OnKeyReleased(unsigned int code)189 	void OnKeyReleased (unsigned int code) {if (m_nState & code) m_nState -= code; OnChangeState ();}
190 /*!
191 Called by the framework for the active tool when a key press event occurs. Default
192 just returns \a false.
193 
194 @return true to stop any further propagation of the event, false otherwise.
195 */
196 	virtual bool OnKeyPress (GdkEventKey *event);
197 /*!
198 Called by the framework for the active tool when a key release event occurs. Default
199 just returns \a false.
200 
201 @return true to stop any further propagation of the event, false otherwise.
202 */
203 	virtual bool OnKeyRelease (GdkEventKey *event);
204 /*!
205 Virtual method called by the framework whenthe active view, and hence the active
206 document has changed, so that the tool can finish its current operation in the
207 previously active document and update its options box according to
208 the new active document settings.
209 @return true to accept the document change, false if something went wrong and the
210 active document should not change, as in the case of the fragment tool when
211 the symbols entered can't be interpreted.
212 */
213 	virtual bool NotifyViewChange ();
214 /*!
215 Called by the framework to delete the selection. Tools for which it is meaningful
216 must have an overriden version of this method.
217 */
218 	virtual bool DeleteSelection ();
219 /*!
220 Called by the framework to delete the selection. Tools for which it is meaningful
221 must have an overriden version of this method.
222 */
223 	virtual bool CopySelection (GtkClipboard *clipboard);
224 /*!
225 Called by the framework to copy the selection. Tools for which it is meaningful
226 must have an oveeriden version of this method.
227 */
228 	virtual bool CutSelection (GtkClipboard *clipboard);
229 /*!
230 Called by the framework to cut the selection. Tools for which it is meaningful
231 must have an overriden version of this method.
232 */
233 	virtual bool PasteSelection (GtkClipboard *clipboard);
234 /*!
235 Called by the framework to paste data. Tools for which it is meaningful
236 must have an overriden version of this method.
237 */
238 	virtual void AddSelection (WidgetData* data);
239 /*!
240 Called by the framework when clipboard data are available. Tools for which this
241 is meaningful must have an overriden version of this method.
242 */
243 	virtual bool OnReceive (GtkClipboard *clipboard, GtkSelectionData *data, int type);
244 /*!
245 Called by the framework when the user requests to undo the last change. Tools
246 such as text editing tools for which this
247 is meaningful must have an overriden version of this method.
248 */
249 	virtual bool OnUndo ();
250 /*!
251 Called by the framework when the user requests to redo the last undone change.
252 Tools such as text editing tools for which this
253 is meaningful must have an overriden version of this method.
254 */
255 	virtual bool OnRedo ();
256 /*!
257 @param node an xml node to push on the tools private undo stack.
258 
259 Used to store a node after a change while editing a text object by text tools.
260 */
261 	virtual void PushNode (xmlNodePtr node);
262 /*!
263 Gets the property page for the tool. Called the first time the tool becomes
264 active.
265 @return the new tool property page.
266 */
267 	virtual GtkWidget *GetPropertyPage ();
268 /*!
269 Gets the tag used to display the appropriate help topic when the user presses
270 the help button in the tools box. The framework will prefix the result with
271 the application name. The text tool in GChemPaint returns "text" which becomes
272 "gchempaint-text".
273 @return the help tag for the tool.
274 */
GetHelpTag()275 	virtual char const *GetHelpTag () {return "";}
276 /*!
277 Gets the Application instance owning the tool.
278 @return the Application instance.
279 */
GetApplication()280 	Application * GetApplication () {return m_pApp;}
281 /*!
282 Callback for a settings change event. Only tools which are dependent on some
283 configuration key need to override this method. Default does nothing.
284 */
OnConfigChanged()285 	virtual void OnConfigChanged () {}
286 
287 protected:
288 /*!
289 Called from OnClicked(View*,gcu::Object*,double,doubl,unsigned int) when a
290 click occured. This method must be overriden in
291 derived classes, and return true if the drag and release events are meaningful
292 for the tool in the current context. Default implementation does nothing and
293 returns false.
294 
295 @return true if drag and release events are needed, false otherwise.
296 */
297 	virtual bool OnClicked ();
298 /*!
299 Called from OnDrag(double,double,unsigned int) when a drag event occured
300 occured. This method must be overriden in
301 derived classes if drag events are meaningful for the tool.
302 Default implementation does nothing.
303 */
304 	virtual void OnDrag ();
305 /*!
306 Called from OnMotion(gcp::View,double,double,unsigned int) when a motion event
307 occured. This method must be overriden in
308 derived classes if motion events are meaningful for the tool.
309 Default implementation does nothing.
310 */
311 	virtual void OnMotion ();
312 /*!
313 Called from OnLeaveNotify(gcp::View,unsigned int) when a leave notify event
314 occured. This method must be overriden in
315 derived classes if leave notify events are meaningful for the tool.
316 Default implementation does nothing.
317 */
318 	virtual void OnLeaveNotify ();
319 /*!
320 Called from OnRelease(double,double,unsigned int) when a button release
321 event occured. This method must be overriden in
322 derived classes if button release events are meaningful for the tool.
323 Default implementation does nothing.
324 */
325 	virtual void OnRelease ();
326 /*!
327 Called when a modifier key has been pressed or released, and fires a drag
328 event so that the tool can update things if necessary.
329 */
330 	virtual void OnChangeState ();
331 
332 protected:
333 /*!
334 x coordinate for the last mouse click (unless the tool modified it).
335 */
336 	double m_x0;
337 /*!
338 y coordinate for the last mouse click (unless the tool modified it).
339 */
340 	double m_y0;
341 /*!
342 x coordinate for the last mouse click (unless the tool modified it). It might
343 be used by tools necessitating two pairs of coordinates.
344 */
345 	double m_x1;
346 /*!
347 y coordinate for the last mouse click (unless the tool modified it). It might
348 be used by tools necessitating two pairs of coordinates.
349 */
350 	double m_y1;
351 /*!
352 The current x position of the mouse cursor.
353 */
354 	double m_x;
355 /*!
356 The current y position of the mouse cursor.
357 */
358 	double m_y;
359 /*!
360 The object on which the last click occured or NULL.
361 */
362 	gcu::Object *m_pObject;
363 /*!
364 The group to which m_pObject belongs if any.
365 */
366 	gcu::Object *m_pObjectGroup;
367 /*!
368 The active gcp::View.
369 */
370 	View *m_pView;
371 /*!
372 The widget data for the current active canvas.
373 */
374 	WidgetData *m_pData;
375 /*!
376 The active canvas widget.
377 */
378 	GtkWidget *m_pWidget;
379 /*!
380 The item on which the last click occured if any.
381 */
382 	gccv::Item *m_Item;
383 /*!
384 The zoom factor when the click occured.
385 */
386 	double m_dZoomFactor;
387 /*!
388 Flag that might be used by tools to store whether they changed something
389 since the last click (and before releasing the button).
390 */
391 	bool m_bChanged;
392 /*!
393 The state of modifier keys as a GdkModifierType values combination.
394 */
395 	unsigned int m_nState;
396 /*!
397 The application owning the tool.
398 */
399 	gcp::Application *m_pApp;
400 /*!
401 A set of modified objects tools might use to track what they did modify.
402 */
403 	std::set<std::string> ModifiedObjects;
404 /*!
405 if true, the intended operation is allowed. Default value is true, each tool must set
406 this flag to false if necessary.
407 */
408 	bool m_bAllowed;
409 
410 private:
411 	double lastx, lasty;
412 	std::string name;
413 	bool m_bPressed;
414 
415 /*!\var m_OwnStatus
416 Whether the tool owns the status bar text.
417 */
418 /*!\fn GetOwnStatus()
419 @return whether the tool owns the status bar text.
420 */
421 GCU_PROT_PROP (bool, OwnStatus)
422 };
423 
424 }	// namespace gcp
425 
426 #endif // GCHEMPAINT_TOOL_H
427