mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2026-05-11 18:02:46 +00:00
535 lines
15 KiB
C++
535 lines
15 KiB
C++
// Copyright (C) 2005 Davis E. King (davis@dlib.net), Keita Mochizuki
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_DRAWABLe_CPP_
|
|
#define DLIB_DRAWABLe_CPP_
|
|
|
|
#include "drawable.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------- drawable_window object ------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
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();
|
|
// now repaint the window
|
|
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())
|
|
{
|
|
// only dispatch a draw() call if this widget isn't hidden
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------- drawable object ----------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
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)
|
|
{
|
|
// this drawable is the first widget at this z order so we need
|
|
// to make its containing set
|
|
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)
|
|
{
|
|
// first remove this drawable from widgets
|
|
drawable_window::set_of_drawables* sod = parent.widgets[z_order_value];
|
|
drawable* junk;
|
|
sod->remove(this,junk);
|
|
|
|
// if there are no more drawables at this z order then destroy the
|
|
// set for this order
|
|
if (sod->size() == 0)
|
|
parent.widgets.destroy(z_order_value);
|
|
|
|
// now add this drawable to its new z order
|
|
sod = parent.widgets[order];
|
|
if (sod == 0)
|
|
{
|
|
// this drawable is the first widget at this z order so we need
|
|
// to make its containing set
|
|
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;
|
|
// first remove this drawable from widgets
|
|
drawable_window::set_of_drawables* sod = parent.widgets[z_order_value];
|
|
drawable* junk;
|
|
sod->remove(this,junk);
|
|
|
|
// if there are no more drawables at this z order then destroy the
|
|
// set for this order
|
|
if (sod->size() == 0)
|
|
parent.widgets.destroy(z_order_value);
|
|
|
|
parent.widget_set.remove(this,junk);
|
|
|
|
// now unregister this drawable from all the events it has registered for.
|
|
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 (
|
|
)
|
|
{
|
|
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
|
|
);
|
|
disable_events();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
#endif // DLIB_DRAWABLe_CPP_
|
|
|