1 // Copyright (C) 2005 Davis E. King (davis@dlib.net), Keita Mochizuki 2 // License: Boost Software License See LICENSE.txt for the full license. 3 4 #ifndef DLIB_DRAWABLe_ 5 #define DLIB_DRAWABLe_ 6 7 #include <memory> 8 9 #include "drawable_abstract.h" 10 #include "../gui_core.h" 11 #include "../set.h" 12 #include "../binary_search_tree.h" 13 #include "../algs.h" 14 #include "../pixel.h" 15 #include "fonts.h" 16 #include "../matrix.h" 17 #include "canvas_drawing.h" 18 19 namespace dlib 20 { 21 22 // ---------------------------------------------------------------------------------------- 23 // ---------------------------------------------------------------------------------------- 24 // class drawable_window 25 // ---------------------------------------------------------------------------------------- 26 // ---------------------------------------------------------------------------------------- 27 28 class drawable; 29 class drawable_window : public base_window 30 { 31 /*! 32 INITIAL VALUE 33 - lastx == -1 34 - lasty == -1 35 - event_id == 1 36 37 CONVENTION 38 - bg_color == background_color() 39 40 - widgets == this binary search tree contains every drawable that is in 41 this window. It is a mapping of each drawable's z-order to a pointer 42 to said drawable. 43 - widget_set == a set that contains all the widgets in this window and 44 want to receive events. 45 46 - mouse_move == this is a set of drawables that are in this window and 47 want to receive the mouse movement events. 48 - mouse_wheel == this is a set of drawables that are in this window and 49 want to receive the mouse wheel events. 50 - mouse_click == this is a set of drawables that are in this window and 51 want to receive the mouse click events. 52 - window_resized == this is a set of drawables that are in this window and 53 want to receive the window_resized event. 54 - keyboard == this is a set of drawables that are in this window and 55 want to receive keyboard events. 56 - focus == this is a set of drawables that are in this window and 57 want to receive focus events. 58 - window_moved == this is a set of drawables that are in this window and 59 want to receive window move events. 60 61 - lastx == the x coordinate that we last saw the mouse at or -1 if the 62 mouse is outside this window. 63 - lasty == the y coordinate that we last saw the mouse at or -1 if the 64 mouse is outside this window. 65 66 - event_id == a number we use to tag events so we don't end up sending 67 an event to a drawable more than once. This could happen if one of the 68 event handlers does something to reset the enumerator while we are 69 dispatching events (e.g. creating a new widget). 70 !*/ 71 public: 72 73 drawable_window( 74 bool resizable = true, 75 bool undecorated = false 76 ) : base_window(resizable,undecorated)77 base_window(resizable,undecorated), 78 bg_color(rgb_pixel(212,208,200)), 79 lastx(-1), 80 lasty(-1), 81 event_id(1) 82 {} 83 84 void set_background_color ( 85 unsigned long red, 86 unsigned long green, 87 unsigned long blue 88 ); 89 90 rgb_pixel background_color ( 91 ) const; 92 93 virtual inline ~drawable_window()=0; 94 95 private: 96 97 void paint ( 98 const canvas& c 99 ); 100 101 protected: 102 103 void on_window_resized( 104 ); 105 106 void on_window_moved( 107 ); 108 109 void on_mouse_down ( 110 unsigned long btn, 111 unsigned long state, 112 long x, 113 long y, 114 bool is_double_click 115 ); 116 117 void on_mouse_up ( 118 unsigned long btn, 119 unsigned long state, 120 long x, 121 long y 122 ); 123 124 void on_mouse_move ( 125 unsigned long state, 126 long x, 127 long y 128 ); 129 130 void on_mouse_leave ( 131 ); 132 133 void on_mouse_enter ( 134 ); 135 136 void on_wheel_up ( 137 unsigned long state 138 ); 139 140 void on_wheel_down ( 141 unsigned long state 142 ); 143 144 void on_focus_gained ( 145 ); 146 147 void on_focus_lost ( 148 ); 149 150 void on_keydown ( 151 unsigned long key, 152 bool is_printable, 153 unsigned long state 154 ); 155 156 void on_string_put ( 157 const std::wstring &str 158 ); 159 160 void on_user_event ( 161 void* p, 162 int i 163 ); 164 165 private: 166 167 friend class drawable; 168 169 170 rgb_pixel bg_color; 171 172 typedef set<drawable*>::kernel_1a_c set_of_drawables; 173 174 binary_search_tree<long,set_of_drawables>::kernel_1a_c widgets; 175 176 set_of_drawables widget_set; 177 set_of_drawables mouse_move; 178 set_of_drawables mouse_wheel; 179 set_of_drawables mouse_click; 180 set_of_drawables window_resized; 181 set_of_drawables keyboard; 182 set_of_drawables focus; 183 set_of_drawables window_moved; 184 set_of_drawables string_put; 185 186 long lastx, lasty; 187 unsigned long event_id; 188 189 190 // restricted functions 191 drawable_window(drawable_window&); // copy constructor 192 drawable_window& operator=(drawable_window&); // assignment operator 193 194 195 }; 196 ~drawable_window()197 drawable_window::~drawable_window(){ close_window();} 198 199 // ---------------------------------------------------------------------------------------- 200 // ---------------------------------------------------------------------------------------- 201 // class drawable 202 // ---------------------------------------------------------------------------------------- 203 // ---------------------------------------------------------------------------------------- 204 205 enum 206 { 207 MOUSE_MOVE = 1, 208 MOUSE_CLICK = 2, 209 MOUSE_WHEEL = 4, 210 WINDOW_RESIZED = 8, 211 KEYBOARD_EVENTS = 16, 212 FOCUS_EVENTS = 32, 213 WINDOW_MOVED = 64, 214 STRING_PUT = 128 215 }; 216 217 class drawable 218 { 219 220 /*! 221 INITIAL VALUE 222 - enabled_events == false 223 - event_id == 0 224 225 CONVENTION 226 - events == a bitset specifying what events this drawable is to receive. 227 228 - z_order_value == z_order() 229 230 - if (this drawable has been added to the parent window's sets and 231 binary search tree) then 232 - enabled_events == true 233 - else 234 - enabled_events == false 235 236 - event_id == the id of the last event we got from our parent window 237 !*/ 238 239 public: 240 241 friend class drawable_window; 242 243 drawable ( 244 drawable_window& w, 245 unsigned long events_ = 0 246 ) : 247 m(w.wm), 248 parent(w), 249 hidden(false), 250 enabled(true), 251 lastx(w.lastx), 252 lasty(w.lasty), 253 mfont(default_font::get_font()), 254 z_order_value(0), 255 events(events_), 256 enabled_events(false), 257 event_id(0) 258 {} 259 260 virtual ~drawable ( 261 ); 262 z_order()263 long z_order ( 264 ) const 265 { 266 m.lock(); 267 long temp = z_order_value; 268 m.unlock(); 269 return temp; 270 } 271 272 virtual void set_z_order ( 273 long order 274 ); 275 get_rect()276 const rectangle get_rect ( 277 ) const 278 { 279 auto_mutex M(m); 280 return rect; 281 } 282 bottom()283 long bottom ( 284 ) const 285 { 286 auto_mutex M(m); 287 return rect.bottom(); 288 } 289 top()290 long top ( 291 ) const 292 { 293 auto_mutex M(m); 294 return rect.top(); 295 } 296 left()297 long left ( 298 ) const 299 { 300 auto_mutex M(m); 301 return rect.left(); 302 } 303 right()304 long right ( 305 ) const 306 { 307 auto_mutex M(m); 308 return rect.right(); 309 } 310 width()311 long width ( 312 ) const 313 { 314 auto_mutex M(m); 315 return rect.width(); 316 } 317 height()318 long height ( 319 ) const 320 { 321 auto_mutex M(m); 322 return rect.height(); 323 } 324 is_enabled()325 bool is_enabled ( 326 ) const 327 { 328 auto_mutex M(m); 329 return enabled; 330 } 331 enable()332 virtual void enable ( 333 ) 334 { 335 auto_mutex M(m); 336 enabled = true; 337 parent.invalidate_rectangle(rect); 338 } 339 disable()340 virtual void disable ( 341 ) 342 { 343 auto_mutex M(m); 344 enabled = false; 345 parent.invalidate_rectangle(rect); 346 } 347 set_main_font(const std::shared_ptr<font> & f)348 virtual void set_main_font ( 349 const std::shared_ptr<font>& f 350 ) 351 { 352 auto_mutex M(m); 353 mfont = f; 354 parent.invalidate_rectangle(rect); 355 } 356 main_font()357 const std::shared_ptr<font> main_font ( 358 ) const 359 { 360 auto_mutex M(m); 361 return mfont; 362 } 363 is_hidden()364 bool is_hidden ( 365 ) const 366 { 367 auto_mutex M(m); 368 return hidden; 369 } 370 set_pos(long x,long y)371 virtual void set_pos ( 372 long x, 373 long y 374 ) 375 { 376 m.lock(); 377 rectangle old(rect); 378 379 const unsigned long width = rect.width(); 380 const unsigned long height = rect.height(); 381 rect.set_top(y); 382 rect.set_left(x); 383 rect.set_right(static_cast<long>(x+width)-1); 384 rect.set_bottom(static_cast<long>(y+height)-1); 385 386 parent.invalidate_rectangle(rect+old); 387 m.unlock(); 388 } 389 show()390 virtual void show ( 391 ) 392 { 393 m.lock(); 394 hidden = false; 395 parent.invalidate_rectangle(rect); 396 m.unlock(); 397 } 398 hide()399 virtual void hide ( 400 ) 401 { 402 m.lock(); 403 hidden = true; 404 parent.invalidate_rectangle(rect); 405 m.unlock(); 406 } 407 parent_window()408 base_window& parent_window ( 409 ) { return parent; } 410 parent_window()411 const base_window& parent_window ( 412 ) const { return parent; } 413 next_free_user_event_number()414 virtual int next_free_user_event_number ( 415 )const { return 0; } 416 417 protected: 418 rectangle rect; 419 const rmutex& m; 420 drawable_window& parent; 421 bool hidden; 422 bool enabled; 423 const long& lastx; 424 const long& lasty; 425 std::shared_ptr<font> mfont; 426 427 428 void enable_events ( 429 ); 430 events_are_enabled()431 bool events_are_enabled ( 432 ) const { auto_mutex M(m); return enabled_events; } 433 434 void disable_events ( 435 ); 436 437 private: 438 439 long z_order_value; 440 const unsigned long events; 441 bool enabled_events; 442 unsigned long event_id; 443 444 445 // restricted functions 446 drawable(drawable&); // copy constructor 447 drawable& operator=(drawable&); // assignment operator 448 449 450 protected: 451 452 virtual void draw ( 453 const canvas& c 454 ) const=0; 455 on_user_event(int)456 virtual void on_user_event ( 457 int 458 ){} 459 on_window_resized()460 virtual void on_window_resized( 461 ){} 462 on_window_moved()463 virtual void on_window_moved( 464 ){} 465 on_mouse_down(unsigned long,unsigned long,long,long,bool)466 virtual void on_mouse_down ( 467 unsigned long , 468 unsigned long , 469 long , 470 long , 471 bool 472 ){} 473 on_mouse_up(unsigned long,unsigned long,long,long)474 virtual void on_mouse_up ( 475 unsigned long , 476 unsigned long , 477 long , 478 long 479 ){} 480 on_mouse_move(unsigned long,long,long)481 virtual void on_mouse_move ( 482 unsigned long , 483 long , 484 long 485 ){} 486 on_mouse_leave()487 virtual void on_mouse_leave ( 488 ){} 489 on_mouse_enter()490 virtual void on_mouse_enter ( 491 ){} 492 on_wheel_up(unsigned long)493 virtual void on_wheel_up ( 494 unsigned long 495 ){} 496 on_wheel_down(unsigned long)497 virtual void on_wheel_down ( 498 unsigned long 499 ){} 500 on_focus_gained()501 virtual void on_focus_gained ( 502 ){} 503 on_focus_lost()504 virtual void on_focus_lost ( 505 ){} 506 on_keydown(unsigned long,bool,unsigned long)507 virtual void on_keydown ( 508 unsigned long , 509 bool , 510 unsigned long 511 ){} 512 on_string_put(const std::wstring &)513 virtual void on_string_put ( 514 const std::wstring& 515 ){} 516 }; 517 518 // ---------------------------------------------------------------------------------------- 519 520 } 521 522 #ifdef NO_MAKEFILE 523 #include "drawable.cpp" 524 #endif 525 526 #endif // DLIB_DRAWABLe_ 527 528