|
|
|
|
|
#ifndef DLIB_DRAWABLe_CPP_ |
|
#define DLIB_DRAWABLe_CPP_ |
|
|
|
#include "drawable.h" |
|
|
|
#include <algorithm> |
|
#include <iostream> |
|
|
|
namespace dlib |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rgb_pixel drawable_window:: |
|
background_color ( |
|
) const |
|
{ |
|
auto_mutex M(wm); |
|
return bg_color; |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
set_background_color ( |
|
unsigned long red_, |
|
unsigned long green_, |
|
unsigned long blue_ |
|
) |
|
{ |
|
wm.lock(); |
|
bg_color.red = red_; |
|
bg_color.green = green_; |
|
bg_color.blue = blue_; |
|
wm.unlock(); |
|
|
|
unsigned long width,height; |
|
get_size(width,height); |
|
rectangle rect(0,0,width-1,height-1); |
|
invalidate_rectangle(rect); |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
paint ( |
|
const canvas& c |
|
) |
|
{ |
|
++event_id; |
|
c.fill(bg_color.red,bg_color.green,bg_color.blue); |
|
|
|
widgets.reset(); |
|
while (widgets.move_next()) |
|
{ |
|
widgets.element().value().reset(); |
|
while (widgets.element().value().move_next()) |
|
{ |
|
|
|
if (widgets.element().value().element()->hidden == false && |
|
widgets.element().value().element()->event_id != event_id) |
|
{ |
|
widgets.element().value().element()->event_id = event_id; |
|
widgets.element().value().element()->draw(c); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_user_event ( |
|
void* p, |
|
int i |
|
) |
|
{ |
|
drawable* d = static_cast<drawable*>(p); |
|
if (widget_set.is_member(d)) |
|
{ |
|
d->on_user_event(i); |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_window_moved( |
|
) |
|
{ |
|
++event_id; |
|
window_moved.reset(); |
|
while (window_moved.move_next()) |
|
{ |
|
if (window_moved.element()->event_id != event_id) |
|
{ |
|
window_moved.element()->event_id = event_id; |
|
window_moved.element()->on_window_moved(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_window_resized( |
|
) |
|
{ |
|
++event_id; |
|
window_resized.reset(); |
|
while (window_resized.move_next()) |
|
{ |
|
if (window_resized.element()->event_id != event_id) |
|
{ |
|
window_resized.element()->event_id = event_id; |
|
window_resized.element()->on_window_resized(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_keydown ( |
|
unsigned long key, |
|
bool is_printable, |
|
unsigned long state |
|
) |
|
{ |
|
++event_id; |
|
keyboard.reset(); |
|
while (keyboard.move_next()) |
|
{ |
|
if (keyboard.element()->event_id != event_id) |
|
{ |
|
keyboard.element()->event_id = event_id; |
|
keyboard.element()->on_keydown(key,is_printable,state); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_focus_gained ( |
|
) |
|
{ |
|
++event_id; |
|
focus.reset(); |
|
while (focus.move_next()) |
|
{ |
|
if (focus.element()->event_id != event_id) |
|
{ |
|
focus.element()->event_id = event_id; |
|
focus.element()->on_focus_gained(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_focus_lost ( |
|
) |
|
{ |
|
++event_id; |
|
focus.reset(); |
|
while (focus.move_next()) |
|
{ |
|
if (focus.element()->event_id != event_id) |
|
{ |
|
focus.element()->event_id = event_id; |
|
focus.element()->on_focus_lost(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_mouse_down ( |
|
unsigned long btn, |
|
unsigned long state, |
|
long x, |
|
long y, |
|
bool is_double_click |
|
) |
|
{ |
|
lastx = x; |
|
lasty = y; |
|
|
|
++event_id; |
|
mouse_click.reset(); |
|
while (mouse_click.move_next()) |
|
{ |
|
if (mouse_click.element()->event_id != event_id) |
|
{ |
|
mouse_click.element()->event_id = event_id; |
|
mouse_click.element()->on_mouse_down(btn,state,x,y,is_double_click); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_mouse_up ( |
|
unsigned long btn, |
|
unsigned long state, |
|
long x, |
|
long y |
|
) |
|
{ |
|
lastx = x; |
|
lasty = y; |
|
|
|
++event_id; |
|
mouse_click.reset(); |
|
while (mouse_click.move_next()) |
|
{ |
|
if (mouse_click.element()->event_id != event_id) |
|
{ |
|
mouse_click.element()->event_id = event_id; |
|
mouse_click.element()->on_mouse_up(btn,state,x,y); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_mouse_move ( |
|
unsigned long state, |
|
long x, |
|
long y |
|
) |
|
{ |
|
lastx = x; |
|
lasty = y; |
|
|
|
++event_id; |
|
mouse_move.reset(); |
|
while (mouse_move.move_next()) |
|
{ |
|
if (mouse_move.element()->event_id != event_id) |
|
{ |
|
mouse_move.element()->event_id = event_id; |
|
mouse_move.element()->on_mouse_move(state,x,y); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_mouse_leave ( |
|
) |
|
{ |
|
lastx = -1; |
|
lasty = -1; |
|
|
|
++event_id; |
|
mouse_move.reset(); |
|
while (mouse_move.move_next()) |
|
{ |
|
if (mouse_move.element()->event_id != event_id) |
|
{ |
|
mouse_move.element()->event_id = event_id; |
|
mouse_move.element()->on_mouse_leave(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_mouse_enter ( |
|
) |
|
{ |
|
++event_id; |
|
mouse_move.reset(); |
|
while (mouse_move.move_next()) |
|
{ |
|
if (mouse_move.element()->event_id != event_id) |
|
{ |
|
mouse_move.element()->event_id = event_id; |
|
mouse_move.element()->on_mouse_enter(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_wheel_up ( |
|
unsigned long state |
|
) |
|
{ |
|
++event_id; |
|
mouse_wheel.reset(); |
|
while (mouse_wheel.move_next()) |
|
{ |
|
if (mouse_wheel.element()->event_id != event_id) |
|
{ |
|
mouse_wheel.element()->event_id = event_id; |
|
mouse_wheel.element()->on_wheel_up(state); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_wheel_down ( |
|
unsigned long state |
|
) |
|
{ |
|
++event_id; |
|
mouse_wheel.reset(); |
|
while (mouse_wheel.move_next()) |
|
{ |
|
if (mouse_wheel.element()->event_id != event_id) |
|
{ |
|
mouse_wheel.element()->event_id = event_id; |
|
mouse_wheel.element()->on_wheel_down(state); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable_window:: |
|
on_string_put ( |
|
const std::wstring &str |
|
) |
|
{ |
|
++event_id; |
|
string_put.reset(); |
|
while (string_put.move_next()) |
|
{ |
|
if (string_put.element()->event_id != event_id) |
|
{ |
|
string_put.element()->event_id = event_id; |
|
string_put.element()->on_string_put(str); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void drawable:: |
|
enable_events ( |
|
) |
|
{ |
|
auto_mutex M(m); |
|
if (enabled_events == false) |
|
{ |
|
enabled_events = true; |
|
drawable* temp = this; |
|
long zo = z_order_value; |
|
|
|
drawable_window::set_of_drawables* sod = parent.widgets[zo]; |
|
if (sod == 0) |
|
{ |
|
|
|
|
|
drawable_window::set_of_drawables s; |
|
s.add(temp); |
|
parent.widgets.add(zo,s); |
|
} |
|
else |
|
{ |
|
sod->add(temp); |
|
} |
|
|
|
temp = this; |
|
parent.widget_set.add(temp); |
|
|
|
if (events & MOUSE_MOVE) |
|
{ |
|
temp = this; |
|
parent.mouse_move.add(temp); |
|
} |
|
if (events & MOUSE_CLICK) |
|
{ |
|
temp = this; |
|
parent.mouse_click.add(temp); |
|
} |
|
if (events & MOUSE_WHEEL) |
|
{ |
|
temp = this; |
|
parent.mouse_wheel.add(temp); |
|
} |
|
if (events & WINDOW_RESIZED) |
|
{ |
|
temp = this; |
|
parent.window_resized.add(temp); |
|
} |
|
if (events & KEYBOARD_EVENTS) |
|
{ |
|
temp = this; |
|
parent.keyboard.add(temp); |
|
} |
|
if (events & FOCUS_EVENTS) |
|
{ |
|
temp = this; |
|
parent.focus.add(temp); |
|
} |
|
if (events & WINDOW_MOVED) |
|
{ |
|
temp = this; |
|
parent.window_moved.add(temp); |
|
} |
|
if (events & STRING_PUT) |
|
{ |
|
temp = this; |
|
parent.string_put.add(temp); |
|
} |
|
parent.invalidate_rectangle(rect); |
|
} |
|
} |
|
|
|
|
|
|
|
void drawable:: |
|
set_z_order ( |
|
long order |
|
) |
|
{ |
|
auto_mutex M(m); |
|
if (order != z_order_value && enabled_events) |
|
{ |
|
|
|
drawable_window::set_of_drawables* sod = parent.widgets[z_order_value]; |
|
drawable* junk; |
|
sod->remove(this,junk); |
|
|
|
|
|
|
|
if (sod->size() == 0) |
|
parent.widgets.destroy(z_order_value); |
|
|
|
|
|
sod = parent.widgets[order]; |
|
if (sod == 0) |
|
{ |
|
|
|
|
|
drawable_window::set_of_drawables s, x; |
|
s.add(junk); |
|
long temp_order = order; |
|
parent.widgets.add(temp_order,s); |
|
} |
|
else |
|
{ |
|
sod->add(junk); |
|
} |
|
parent.invalidate_rectangle(rect); |
|
|
|
} |
|
z_order_value = order; |
|
} |
|
|
|
|
|
|
|
void drawable:: |
|
disable_events ( |
|
) |
|
{ |
|
auto_mutex M(m); |
|
if (enabled_events) |
|
{ |
|
enabled_events = false; |
|
|
|
drawable_window::set_of_drawables* sod = parent.widgets[z_order_value]; |
|
drawable* junk; |
|
sod->remove(this,junk); |
|
|
|
|
|
|
|
if (sod->size() == 0) |
|
parent.widgets.destroy(z_order_value); |
|
|
|
parent.widget_set.remove(this,junk); |
|
|
|
|
|
if (events & MOUSE_MOVE) |
|
parent.mouse_move.remove(this,junk); |
|
if (events & MOUSE_CLICK) |
|
parent.mouse_click.remove(this,junk); |
|
if (events & MOUSE_WHEEL) |
|
parent.mouse_wheel.remove(this,junk); |
|
if (events & WINDOW_RESIZED) |
|
parent.window_resized.remove(this,junk); |
|
if (events & KEYBOARD_EVENTS) |
|
parent.keyboard.remove(this,junk); |
|
if (events & FOCUS_EVENTS) |
|
parent.focus.remove(this,junk); |
|
if (events & WINDOW_MOVED) |
|
parent.window_moved.remove(this,junk); |
|
if (events & STRING_PUT) |
|
parent.string_put.remove(this,junk); |
|
} |
|
} |
|
|
|
|
|
|
|
drawable:: |
|
~drawable ( |
|
) |
|
{ |
|
try |
|
{ |
|
DLIB_ASSERT(events_are_enabled() == false, |
|
"\tdrawable::~drawable()" |
|
<< "\n\tYou must disable events for drawable objects in their destructor by calling disable_events()." |
|
<< "\n\tthis: " << this |
|
); |
|
} |
|
catch (std::exception& e) |
|
{ |
|
std::cerr << e.what() << std::endl; |
|
assert(false); |
|
abort(); |
|
} |
|
disable_events(); |
|
} |
|
|
|
|
|
|
|
} |
|
|
|
#endif |
|
|
|
|