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 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 82 tip_entry( 83 BRect _rect) : 84 rect(_rect) {} 85 86 // give the compiler some slack: 87 tip_entry() {} 88 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: 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(); 146 _ViewEntry() {} 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 185 BView* target() const { return m_target; } 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(); 214 _WindowEntry() {} 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 245 BWindow* target() const { return m_target; } 246 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