1/*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions, and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions, and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * 3. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32// DiagramItem.h (Cortex/DiagramView)
33//
34// * PURPOSE
35//   Provides a base class for all items that can be handled
36//   by the DiagramView implementation. A basic interface with
37//	 some common implementation is defined, with methods related
38//   to drawing, mouse handling, selecting, dragging, comparison
39//   for sorting, and access to the drawing context which is the
40//   DiagramView instance.
41//
42// * HISTORY
43//   c.lenz		25sep99		Begun
44//
45
46#ifndef __DiagramItem_H__
47#define __DiagramItem_H__
48
49#include <OS.h>
50#include <InterfaceDefs.h>
51#include <Region.h>
52
53class BMessage;
54class BView;
55
56#include "cortex_defs.h"
57__BEGIN_CORTEX_NAMESPACE
58
59class DiagramItemGroup;
60class DiagramView;
61class DiagramBox;
62
63int compareSelectionTime(const void *lValue, const void *rValue);
64
65class DiagramItem
66{
67	friend class DiagramItemGroup;
68	friend class DiagramView;
69	friend class DiagramBox;
70
71public:					// *** types
72
73	enum diagram_item_t {
74		M_BOX		= 0x1,
75		M_WIRE		= 0x2,
76		M_ENDPOINT	= 0x4,
77		M_ANY		= 0x7
78	};
79
80public:					// *** ctor/dtor
81
82						DiagramItem(
83							uint32 itemType);
84
85	virtual				~DiagramItem();
86
87public:					// *** accessors
88
89	// returns the item type assigned in the ctor
90	uint32				type() const
91						{ return m_type; }
92
93	// returns pointer to the drawing context of the DiagramView
94	// object
95	DiagramView		   *view() const
96						{ return m_view; }
97
98	// returns pointer to the DiagramItemGroup the item belongs to
99	DiagramItemGroup   *group() const
100						{ return m_group; }
101
102	// returns true if the item is currently selected
103	bool				isSelected() const
104						{ return m_selected; }
105
106public:					// *** operations
107
108	// changes the selection state of the item, and updates the
109	// m_selectionTime member in the process to ensure proper
110	// sorting; calls the selected() hook if the state has
111	// actually changed
112	void				select();
113
114	// sets the item to selected without changing m_selectionTime
115	// to the time of selection but prior to the last "replacing"
116	// selection (i.e. thru select()) use this method for additive
117	// selecting; still calls the selected() hook
118	void				selectAdding();
119
120	// deselects the item; calls the deselected() hook if the
121	// state has actually changed
122	void				deselect();
123
124	// moves the items frame to a given point by calling MoveBy with the
125	// absolute coords translated into relative shift amount
126	void				moveTo(
127							BPoint point,
128							BRegion *updateRegion = 0)
129						{ MoveBy(point.x - Frame().left, point.y - Frame().top, updateRegion); }
130
131	// resizes the items frame to given dimensions; simply calls the ResizeBy
132	// implementation
133	void				resizeTo(
134							float width,
135							float height)
136						{ ResizeBy(width - Frame().Width(), height - Frame().Height()); }
137
138public:					// *** hook functions
139
140	// is called when the item has been attached to the DiagramView
141	// and the view() pointer is valid
142	virtual void		attachedToDiagram()
143						{ /* does nothing */ }
144
145	// is called just before the item is being detached from the
146	// the DiagramView
147	virtual void		detachedFromDiagram()
148						{ /* does nothing */ }
149
150	// is called from the DiagramViews MouseDown() function after
151	// finding out the mouse buttons and clicks quantity.
152	virtual void		MouseDown(
153							BPoint point,
154							uint32 buttons,
155							uint32 clicks)
156						{/* does nothing */}
157
158	// is called from the DiagramViews MouseMoved() when *no* message is being
159	// dragged, i.e. the mouse is simply floating above the item
160	virtual void		MouseOver(
161							BPoint point,
162							uint32 transit)
163						{/* does nothing */}
164
165	// is called from the DiagramViews MouseMoved() when a message is being
166	// dragged; always call the base class version when overriding!
167	virtual void		MessageDragged(
168							BPoint point,
169							uint32 transit,
170							const BMessage *message)
171						{/* does nothing */}
172
173	// is called from the DiagramViews MessageReceived() function when an
174	// message has been received through Drag&Drop; always call the base
175	// class version when overriding!
176	virtual void		MessageDropped(
177							BPoint point,
178							BMessage *message)
179						{/* does nothing */}
180
181	// is called when the item has been selected or deselected in some way
182	virtual void		selected()
183						{ /* does nothing */ }
184	virtual void		deselected()
185						{ /* does nothing */ }
186
187public:					// *** interface definition
188
189	// this function must be implemented by derived classes to return the
190	// items frame rectangle in the DiagramViews coordinates
191	virtual BRect		Frame() const = 0;
192
193	// this function should be implemented for non-rectangular subclasses
194	// (like wires) to estimate how close a given point is to the object;
195	// the default implementation returns 1.0 when the point lies within
196	// the Frame() rect and 0.0 if not
197	virtual float		howCloseTo(
198							BPoint point) const;
199
200	// this is the hook function called by DiagramView when it's time to
201	// Draw the object
202	virtual void		Draw(
203							BRect updateRect) = 0;
204
205	// should move the items frame by the specified amount and do the
206	// necessary drawing instructions to update the display; if the
207	// caller supplied a BRegion pointer in updateRegion, this method
208	// should add other areas affected by the move to it (e.g. wire
209	// frames)
210	virtual void		MoveBy(
211							float x,
212							float y,
213							BRegion *updateRegion = 0)
214						{ /* does nothing */ }
215
216	// should resize the items frame by the specified amount
217	virtual void		ResizeBy(
218							float horizontal,
219							float vertical)
220						{ /* does nothing */ }
221
222protected:				// *** selecting/dragging
223
224	// turn on/off the built-in selection handling
225	void				makeSelectable(
226							bool selectable)
227							{ m_selectable = selectable; }
228	bool				isSelectable() const
229							{ return m_selectable; }
230
231	// turn on/off the built-in drag & drop handling
232	void				makeDraggable(
233							bool draggable)
234							{ m_draggable = draggable; }
235	bool				isDraggable() const
236							{ return m_draggable; }
237
238protected:				// *** compare functions
239
240	// compares the time when each item was last selected and
241	// returns -1 for the most recent.
242	friend int			compareSelectionTime(
243							const void *lValue,
244							const void *rValue);
245
246protected:				// *** internal methods
247
248	// called only by DiagramItemGroup objects in the method
249	// addItem()
250	virtual void		_SetOwner(
251							DiagramView *owner)
252						{ m_view = owner; }
253
254private:				// *** data members
255
256	// the items type (M_BOX, M_WIRE or M_ENDPOINT)
257	uint32				m_type;
258
259	// a pointer to the drawing context (the DiagramView instance)
260	DiagramView		   *m_view;
261
262	// a pointer to the DiagramItemGroup the item belongs to
263	DiagramItemGroup   *m_group;
264
265	// can the object be dragged
266	bool				m_draggable;
267
268	// can the object be selected
269	bool				m_selectable;
270
271	// is the object currently selected
272	bool				m_selected;
273
274	// when was the object selected the last time or added (used
275	// for drawing order)
276	bigtime_t			m_selectionTime;
277
278	// stores the most recent time a item was selected thru
279	// the select() method
280	static bigtime_t	m_lastSelectionTime;
281
282	// counts the number of selections thru selectAdding()
283	// since the last call to select()
284	static int32		m_countSelected;
285};
286
287__END_CORTEX_NAMESPACE
288#endif /* __DiagramItem_H__ */
289