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