xref: /haiku/src/apps/cortex/TipManager/TipManagerImpl.h (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
1 // TipManagerImpl.h
2 // e.moon 13may99
3 //
4 // HISTORY
5 //   13may99	e.moon		moved TipManager internals here
6 
7 #ifndef __TIPMANAGERIMPL_H__
8 #define __TIPMANAGERIMPL_H__
9 
10 #include <set>
11 #include <list>
12 #include <utility>
13 
14 #include <Debug.h>
15 #include <SupportDefs.h>
16 #include <Font.h>
17 #include <Point.h>
18 #include <Rect.h>
19 #include <GraphicsDefs.h>
20 #include <String.h>
21 #include <View.h>
22 
23 class BWindow;
24 class BMessageRunner;
25 
26 #include "cortex_defs.h"
27 __BEGIN_CORTEX_NAMESPACE
28 
29 // -------------------------------------------------------- //
30 // tip_entry
31 // -------------------------------------------------------- //
32 
33 class tip_entry {
34 public:													// *** interface
35 	// if rect is invalid, the entry represents the view's entire
36 	// frame area
37 	tip_entry(
38 		BRect												_rect,
39 		const char*									_text,
40 		TipManager::offset_mode_t		_offsetMode,
41 		BPoint											_offset,
42 		uint32											_flags) :
43 
44 		rect(_rect),
45 		text(_text),
46 		offsetMode(_offsetMode),
47 		offset(_offset),
48 		flags(_flags) {}
49 
50 	// useful for comparisons
51 	tip_entry(
52 		BRect												_rect) :
53 		rect(_rect) {}
54 
55 	// give the compiler some slack:
56 	tip_entry() {}
57 
58 	void dump(int indent) {
59 		BString s;
60 		s.SetTo('\t', indent);
61 		PRINT((
62 			"%stip_entry '%s'\n",
63 			s.String(),
64 			text.String()));
65 	}
66 
67 	// +++++ copy ctors and other treats for lame compilers go here +++++
68 
69 	// members
70 	BRect													rect;
71 	BString												text;
72 
73 	TipManager::offset_mode_t			offsetMode;
74 	BPoint 												offset;
75 
76 	uint32 												flags;
77 };
78 
79 // ordering criteria: by top-left corner of the rect,
80 //                    invalid rects last (unsorted)
81 // [13may99: inverted -- which I suppose causes elements to
82 //           be stored in increasing 'order', and therefore
83 //           position]
84 
85 // [e.moon 13oct99] tip_entry instances now stored and compared
86 // by pointer
87 
88 class tip_entry_ptr_less_fn {		public:
89 	bool operator()(
90 		const tip_entry*						a,
91 		const tip_entry*						b) const {
92 		if(a->rect.IsValid())
93 			if(b->rect.IsValid()) {
94 				if(a->rect.left == b->rect.left)
95 					return a->rect.top > b->rect.top;
96 				return a->rect.left > b->rect.left;
97 			}
98 			else
99 				return true;
100 		else
101 			return false;
102 	}
103 };
104 
105 typedef std::set<tip_entry*, tip_entry_ptr_less_fn > tip_entry_set;
106 
107 // -------------------------------------------------------- //
108 // _ViewEntry
109 // -------------------------------------------------------- //
110 
111 class _ViewEntry {
112 public:													// *** interface
113 
114 	virtual ~_ViewEntry();
115 	_ViewEntry() {}
116 	_ViewEntry(
117 		BView*											target,
118 		_ViewEntry*									parent) :
119 		m_target(target),
120 		m_parent(parent) {}
121 
122 	// +++++ copy ctors and other treats for lame compilers go here +++++
123 
124 	// add the given entry for the designated view
125 	// (which may be the target view or a child.)
126 	// returns B_OK on success, B_ERROR if:
127 	// - the given view is NOT a child of the target view
128 	// - or if tips can't be added to this view due to it,
129 	//   or one of its parents, having a full-frame tip.
130 
131 	status_t add(
132 		BView*											view,
133 		const tip_entry&						entry);
134 
135 	// remove tip matching the given rect's upper-left corner or
136 	// all tips if rect is invalid.
137 	// returns B_ERROR on failure -- if there are no entries for
138 	// the given view -- or B_OK otherwise.
139 
140 	status_t remove(
141 		BView*											view,
142 		const BRect&								rect);
143 
144 	// match the given point (in target's view coordinates)
145 	// against tips in this view and child views.
146 
147 	std::pair<BView*, const tip_entry*> match(
148 		BPoint											point,
149 		BPoint											screenPoint);
150 
151 	// retrieve current frame rect (in parent view's coordinates)
152 	BRect frame();
153 
154 	BView* target() const { return m_target; }
155 	_ViewEntry* parent() const { return m_parent; }
156 
157 	size_t countTips() const;
158 
159 	void dump(int indent);
160 
161 private:
162 	// returns pointer to sole entry in the set if it's
163 	// a full-frame tip, or 0 if there's no full-frame tip
164 	const tip_entry* fullFrameTip() const;
165 
166 	// members
167 	BView*												m_target;
168 	_ViewEntry*										m_parent;
169 
170 	// [e.moon 13oct99] child view list now stores pointers
171 	std::list<_ViewEntry*>							m_childViews;
172 	tip_entry_set									m_tips;
173 };
174 
175 // -------------------------------------------------------- //
176 // _WindowEntry
177 // -------------------------------------------------------- //
178 
179 class _WindowEntry {
180 public:													// *** interface
181 
182 	virtual ~_WindowEntry();
183 	_WindowEntry() {}
184 	_WindowEntry(
185 		BWindow*										target) :
186 		m_target(target) {}
187 
188 	// add the given entry for the designated view (which must
189 	// be attached to the target window)
190 	// returns B_OK on success, B_ERROR if:
191 	// - the given view is NOT attached to the target window, or
192 	// - tips can't be added to this view due to it, or one of its
193 	//   parents, having a full-frame tip.
194 
195 	status_t add(
196 		BView*											view,
197 		const tip_entry&						entry);
198 
199 	// remove tip matching the given rect's upper-left corner or
200 	// all tips if rect is invalid.
201 	// returns B_ERROR on failure -- if there are no entries for
202 	// the given view -- or B_OK otherwise.
203 
204 	status_t remove(
205 		BView*											view,
206 		const BRect&								rect);
207 
208 	// match the given point (in screen coordinates)
209 	// against tips in this view and child views.
210 
211 	std::pair<BView*, const tip_entry*> match(
212 		BPoint											screenPoint);
213 
214 	BWindow* target() const { return m_target; }
215 
216 	size_t countViews() const { return m_views.size(); }
217 
218 	void dump(int indent);
219 
220 private:
221 	// the target window
222 	BWindow*											m_target;
223 
224 	// view subtrees with tip entries
225 	std::list<_ViewEntry*>							m_views;
226 };
227 
228 // -------------------------------------------------------- //
229 // _TipManagerView
230 // -------------------------------------------------------- //
231 
232 class _TipManagerView :
233 	public	BView {
234 	typedef	BView _inherited;
235 
236 public:													// *** messages
237 	enum message_t {
238 		// sent
239 		M_TIME_PASSED
240 	};
241 
242 public:													// *** ctor/dtor
243 	virtual ~_TipManagerView();
244 	_TipManagerView(
245 		TipWindow*									tipWindow,
246 		TipManager*									manager,
247 		bigtime_t										updatePeriod,
248 		bigtime_t										idlePeriod);
249 
250 public:													// *** operations
251 
252 	// Prepare a 'one-off' tip: this interrupts normal mouse-watching
253 	// behavior while the mouse remains in the given screen rectangle.
254 	// If it idles long enough, the tip window is displayed.
255 
256 	status_t armTip(
257 		const BRect&								screenRect,
258 		const char*									text,
259 		TipManager::offset_mode_t		offsetMode,
260 		BPoint											offset,
261 		uint32 											flags);
262 
263 	// Hide tip corresponding to the given screenRect, if any.
264 	// [e.moon 29nov99] Cancel 'one-off' tip for the given rect if any.
265 
266 	status_t hideTip(
267 		const BRect&								screenRect);
268 
269 	// Add/replace a tip in the window/view-entry tree
270 
271 	status_t setTip(
272 		const BRect&								rect,
273 		const char*									text,
274 		BView*											view,
275 		TipManager::offset_mode_t		offsetMode,
276 		BPoint											offset,
277 		uint32 											flags);
278 
279 	// Remove a given tip from a particular view in the entry tree
280 	// (if the rect is invalid, removes all tips for that view.)
281 
282 	status_t removeTip(
283 		const BRect&								rect,
284 		BView*											view);
285 
286 	// Remove all tips for the given window from the entry tree.
287 
288 	status_t removeAll(
289 		BWindow*										window);
290 
291 public:													// *** BView
292 
293 	void AttachedToWindow();
294 
295 	void KeyDown(
296 		const char*									bytes,
297 		int32												count);
298 
299 	void MouseDown(
300 		BPoint											point);
301 
302 	void MouseMoved(
303 		BPoint											point,
304 		uint32											orientation,
305 		const BMessage*							dragMessage);
306 
307 public:													// *** BHandler
308 
309 	void MessageReceived(
310 		BMessage*										message);
311 
312 private:												// implementation
313 
314 	// the tip window to be displayed
315 	TipWindow*										m_tipWindow;
316 
317 	// owner
318 	TipManager*										m_manager;
319 
320 	// set of window entries containing one or more bound tip rectangles
321 	std::list<_WindowEntry*>						m_windows;
322 
323 	// update message source
324 	BMessageRunner*								m_messageRunner;
325 
326 	// window state
327 	enum tip_window_state_t {
328 		TIP_WINDOW_HIDDEN,
329 		TIP_WINDOW_VISIBLE,
330 		TIP_WINDOW_ARMED
331 	};
332 	tip_window_state_t						m_tipWindowState;
333 
334 	// how often to check for mouse idleness
335 	bigtime_t											m_updatePeriod;
336 
337 	// how long it takes a tip to fire
338 	bigtime_t											m_idlePeriod;
339 
340 	// mouse-watching state
341 	BPoint												m_lastMousePoint;
342 	bigtime_t											m_lastEventTime;
343 	bool													m_triggered;
344 
345 	// once a tip has been shown, it remains visible while the
346 	// mouse stays within this screen rect
347 	BRect													m_visibleTipRect;
348 
349 	// armTip() state
350 	tip_entry*										m_armedTip;
351 
352 private:
353 
354 	inline void _timePassed();
355 
356 	inline void _showTip(
357 		const tip_entry*						entry);
358 
359 	inline void _hideTip();
360 };
361 
362 __END_CORTEX_NAMESPACE
363 #endif /* __TIPMANAGERIMPL_H__ */
364