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