summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/gui_widgets
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/gui_widgets')
-rw-r--r--ml/dlib/dlib/gui_widgets/base_widgets.cpp3343
-rw-r--r--ml/dlib/dlib/gui_widgets/base_widgets.h2678
-rw-r--r--ml/dlib/dlib/gui_widgets/base_widgets_abstract.h2290
-rw-r--r--ml/dlib/dlib/gui_widgets/canvas_drawing.cpp101
-rw-r--r--ml/dlib/dlib/gui_widgets/canvas_drawing.h964
-rw-r--r--ml/dlib/dlib/gui_widgets/canvas_drawing_abstract.h364
-rw-r--r--ml/dlib/dlib/gui_widgets/drawable.cpp544
-rw-r--r--ml/dlib/dlib/gui_widgets/drawable.h527
-rw-r--r--ml/dlib/dlib/gui_widgets/drawable_abstract.h717
-rw-r--r--ml/dlib/dlib/gui_widgets/fonts.cpp673
-rw-r--r--ml/dlib/dlib/gui_widgets/fonts.h628
-rw-r--r--ml/dlib/dlib/gui_widgets/fonts_abstract.h492
-rw-r--r--ml/dlib/dlib/gui_widgets/nativefont.h612
-rw-r--r--ml/dlib/dlib/gui_widgets/style.cpp998
-rw-r--r--ml/dlib/dlib/gui_widgets/style.h825
-rw-r--r--ml/dlib/dlib/gui_widgets/style_abstract.h777
-rw-r--r--ml/dlib/dlib/gui_widgets/widgets.cpp7341
-rw-r--r--ml/dlib/dlib/gui_widgets/widgets.h4165
-rw-r--r--ml/dlib/dlib/gui_widgets/widgets_abstract.h3461
19 files changed, 0 insertions, 31500 deletions
diff --git a/ml/dlib/dlib/gui_widgets/base_widgets.cpp b/ml/dlib/dlib/gui_widgets/base_widgets.cpp
deleted file mode 100644
index 2f2eb8e9c..000000000
--- a/ml/dlib/dlib/gui_widgets/base_widgets.cpp
+++ /dev/null
@@ -1,3343 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_BASE_WIDGETs_CPP_
-#define DLIB_BASE_WIDGETs_CPP_
-
-#include <iostream>
-#include <memory>
-
-#include "base_widgets.h"
-#include "../assert.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // button object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void button::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- rectangle min_rect = style->get_min_size(name_,*mfont);
- // only change the size if it isn't going to be too small to fit the name
- if (height >= min_rect.height() &&
- width >= min_rect.width())
- {
- rectangle old(rect);
- rect = resize_rect(rect,width,height);
- parent.invalidate_rectangle(style->get_invalidation_rect(rect+old));
- btn_tooltip.set_size(width,height);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- show (
- )
- {
- button_action::show();
- btn_tooltip.show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- hide (
- )
- {
- button_action::hide();
- btn_tooltip.hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- enable (
- )
- {
- button_action::enable();
- btn_tooltip.enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- disable (
- )
- {
- button_action::disable();
- btn_tooltip.disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- set_tooltip_text (
- const std::string& text
- )
- {
- btn_tooltip.set_text(text);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- set_tooltip_text (
- const std::wstring& text
- )
- {
- btn_tooltip.set_text(text);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- set_tooltip_text (
- const ustring& text
- )
- {
- btn_tooltip.set_text(text);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string button::
- tooltip_text (
- ) const
- {
- return btn_tooltip.text();
- }
-
- const std::wstring button::
- tooltip_wtext (
- ) const
- {
- return btn_tooltip.wtext();
- }
-
- const dlib::ustring button::
- tooltip_utext (
- ) const
- {
- return btn_tooltip.utext();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- set_name(name_);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- set_pos (
- long x,
- long y
- )
- {
- auto_mutex M(m);
- button_action::set_pos(x,y);
- btn_tooltip.set_pos(x,y);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- set_name (
- const std::string& name
- )
- {
- set_name(convert_mbstring_to_wstring(name));
- }
-
- void button::
- set_name (
- const std::wstring& name
- )
- {
- set_name(convert_wstring_to_utf32(name));
- }
-
- void button::
- set_name (
- const ustring& name
- )
- {
- auto_mutex M(m);
- name_ = name;
- // do this to get rid of any reference counting that may be present in
- // the std::string implementation.
- name_[0] = name_[0];
-
- rectangle old(rect);
- rect = move_rect(style->get_min_size(name,*mfont),rect.left(),rect.top());
- btn_tooltip.set_size(rect.width(),rect.height());
-
- parent.invalidate_rectangle(style->get_invalidation_rect(rect+old));
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string button::
- name (
- ) const
- {
- auto_mutex M(m);
- std::string temp = convert_wstring_to_mbstring(wname());
- // do this to get rid of any reference counting that may be present in
- // the std::string implementation.
- char c = temp[0];
- temp[0] = c;
- return temp;
- }
-
- const std::wstring button::
- wname (
- ) const
- {
- auto_mutex M(m);
- std::wstring temp = convert_utf32_to_wstring(uname());
- // do this to get rid of any reference counting that may be present in
- // the std::wstring implementation.
- wchar_t w = temp[0];
- temp[0] = w;
- return temp;
- }
-
- const dlib::ustring button::
- uname (
- ) const
- {
- auto_mutex M(m);
- dlib::ustring temp = name_;
- // do this to get rid of any reference counting that may be present in
- // the dlib::ustring implementation.
- temp[0] = name_[0];
- return temp;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- on_button_up (
- bool mouse_over
- )
- {
- if (mouse_over)
- {
- // this is a valid button click
- if (event_handler.is_set())
- event_handler();
- if (event_handler_self.is_set())
- event_handler_self(*this);
- }
- if (button_up_handler.is_set())
- button_up_handler(mouse_over);
- if (button_up_handler_self.is_set())
- button_up_handler_self(mouse_over,*this);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button::
- on_button_down (
- )
- {
- if (button_down_handler.is_set())
- button_down_handler();
- if (button_down_handler_self.is_set())
- button_down_handler_self(*this);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // draggable object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- draggable::~draggable() {}
-
-// ----------------------------------------------------------------------------------------
-
- void draggable::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- if (drag && (state & base_window::LEFT) && enabled && !hidden)
- {
- // the user is trying to drag this object. we should calculate the new
- // x and y positions for the upper left corner of this object's rectangle
-
- long new_x = x - this->x;
- long new_y = y - this->y;
-
- // make sure these points are inside the draggable area.
- if (new_x < area.left())
- new_x = area.left();
- if (new_x + static_cast<long>(rect.width()) - 1 > area.right())
- new_x = area.right() - rect.width() + 1;
-
- if (new_y + static_cast<long>(rect.height()) - 1 > area.bottom())
- new_y = area.bottom() - rect.height() + 1;
- if (new_y < area.top())
- new_y = area.top();
-
- // now make the new rectangle for this object
- rectangle new_rect(
- new_x,
- new_y,
- new_x + rect.width() - 1,
- new_y + rect.height() - 1
- );
-
- // only do anything if this is a new rectangle and it is inside area
- if (new_rect != rect && area.intersect(new_rect) == new_rect)
- {
- parent.invalidate_rectangle(new_rect + rect);
- rect = new_rect;
-
- // call the on_drag() event handler
- on_drag();
- }
- }
- else
- {
- drag = false;
- on_drag_stop();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void draggable::
- on_mouse_up (
- unsigned long ,
- unsigned long state,
- long ,
- long
- )
- {
- if (drag && (state & base_window::LEFT) == 0)
- {
- drag = false;
- on_drag_stop();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void draggable::
- on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- )
- {
- if (enabled && !hidden && rect.contains(x,y) && btn == base_window::LEFT)
- {
- drag = true;
- this->x = x - rect.left();
- this->y = y - rect.top();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // mouse_over_event object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- mouse_over_event::~mouse_over_event() {}
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_over_event::
- on_mouse_leave (
- )
- {
- if (is_mouse_over_)
- {
- is_mouse_over_ = false;
- on_mouse_not_over();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_over_event::
- on_mouse_move (
- unsigned long ,
- long x,
- long y
- )
- {
- if (rect.contains(x,y) == false)
- {
- if (is_mouse_over_)
- {
- is_mouse_over_ = false;
- on_mouse_not_over();
- }
- }
- else if (is_mouse_over_ == false)
- {
- is_mouse_over_ = true;
- if (enabled && !hidden)
- on_mouse_over();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool mouse_over_event::
- is_mouse_over (
- ) const
- {
- // check if the mouse is still really over this button
- if (is_mouse_over_ && rect.contains(lastx,lasty) == false)
- {
- // trigger a user event to call on_mouse_not_over() and repaint this object.
- // we must do this in another event because someone might call is_mouse_over()
- // from draw() and you don't want this function to end up calling
- // parent.invalidate_rectangle(). It would lead to draw() being called over
- // and over.
- parent.trigger_user_event((void*)this,drawable::next_free_user_event_number());
- return false;
- }
-
- return is_mouse_over_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_over_event::
- on_user_event (
- int num
- )
- {
- if (is_mouse_over_ && num == drawable::next_free_user_event_number())
- {
- is_mouse_over_ = false;
- on_mouse_not_over();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // button_action object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- button_action::~button_action() {}
-
-// ----------------------------------------------------------------------------------------
-
- void button_action::
- on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- )
- {
- if (enabled && !hidden && btn == base_window::LEFT && rect.contains(x,y))
- {
- is_depressed_ = true;
- seen_click = true;
- parent.invalidate_rectangle(rect);
- on_button_down();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button_action::
- on_mouse_not_over (
- )
- {
- if (is_depressed_)
- {
- is_depressed_ = false;
- parent.invalidate_rectangle(rect);
- on_button_up(false);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button_action::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- // forward event to the parent class so it can do it's thing as well as us
- mouse_over_event::on_mouse_move(state,x,y);
-
- if (enabled == false || hidden == true)
- return;
-
-
- if ((state & base_window::LEFT) == 0)
- {
- seen_click = false;
- if (is_depressed_)
- {
- is_depressed_ = false;
- parent.invalidate_rectangle(rect);
- on_button_up(false);
- }
-
- // the left button isn't down so we don't care about anything else
- return;
- }
-
- if (rect.contains(x,y) == false)
- {
- if (is_depressed_)
- {
- is_depressed_ = false;
- parent.invalidate_rectangle(rect);
- on_button_up(false);
- }
- }
- else if (is_depressed_ == false && seen_click)
- {
- is_depressed_ = true;
- parent.invalidate_rectangle(rect);
- on_button_down();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button_action::
- on_mouse_up (
- unsigned long btn,
- unsigned long,
- long x,
- long y
- )
- {
- if (enabled && !hidden && btn == base_window::LEFT)
- {
- if (is_depressed_)
- {
- is_depressed_ = false;
- parent.invalidate_rectangle(rect);
-
- if (rect.contains(x,y))
- {
- on_button_up(true);
- }
- else
- {
- on_button_up(false);
- }
- }
- else if (seen_click && rect.contains(x,y))
- {
- // this case here covers the unlikly event that you click on a button,
- // move the mouse off the button and then move it back very quickly and
- // release the mouse button. It is possible that this mouse up event
- // will occurr before any mouse move event so you might not have set
- // that the button is depressed yet.
-
- // So we should say that this triggers an on_button_down() event and
- // then an on_button_up(true) event.
-
- parent.invalidate_rectangle(rect);
-
- on_button_down();
- on_button_up(true);
- }
-
- seen_click = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool button_action::
- is_depressed (
- ) const
- {
- // check if the mouse is still really over this button
- if (enabled && !hidden && is_depressed_ && rect.contains(lastx,lasty) == false)
- {
- // trigger a user event to call on_button_up() and repaint this object.
- // we must do this in another event because someone might call is_depressed()
- // from draw() and you don't want this function to end up calling
- // parent.invalidate_rectangle(). It would lead to draw() being called over
- // and over.
- parent.trigger_user_event((void*)this,mouse_over_event::next_free_user_event_number());
- return false;
- }
-
- return is_depressed_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void button_action::
- on_user_event (
- int num
- )
- {
- // forward event to the parent class so it can do it's thing as well as us
- mouse_over_event::on_user_event(num);
-
- if (is_depressed_ && num == mouse_over_event::next_free_user_event_number())
- {
- is_depressed_ = false;
- parent.invalidate_rectangle(rect);
- on_button_up(false);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // scroll_bar object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- scroll_bar::
- scroll_bar(
- drawable_window& w,
- bar_orientation orientation
- ) :
- drawable(w),
- b1(w),
- b2(w),
- slider(w,*this,&scroll_bar::on_slider_drag),
- ori(orientation),
- top_filler(w,*this,&scroll_bar::top_filler_down,&scroll_bar::top_filler_up),
- bottom_filler(w,*this,&scroll_bar::bottom_filler_down,&scroll_bar::bottom_filler_up),
- pos(0),
- max_pos(0),
- js(10),
- b1_timer(*this,&scroll_bar::b1_down_t),
- b2_timer(*this,&scroll_bar::b2_down_t),
- top_filler_timer(*this,&scroll_bar::top_filler_down_t),
- bottom_filler_timer(*this,&scroll_bar::bottom_filler_down_t)
- {
- set_style(scroll_bar_style_default());
-
- // don't show the slider when there is no place it can move.
- slider.hide();
-
- set_length(100);
-
- b1.set_button_down_handler(*this,&scroll_bar::b1_down);
- b2.set_button_down_handler(*this,&scroll_bar::b2_down);
-
- b1.set_button_up_handler(*this,&scroll_bar::b1_up);
- b2.set_button_up_handler(*this,&scroll_bar::b2_up);
- b1.disable();
- b2.disable();
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- scroll_bar::
- ~scroll_bar(
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- // wait for all the timers to be stopped
- b1_timer.stop_and_wait();
- b2_timer.stop_and_wait();
- top_filler_timer.stop_and_wait();
- bottom_filler_timer.stop_and_wait();
- }
-
-// ----------------------------------------------------------------------------------------
-
- scroll_bar::bar_orientation scroll_bar::
- orientation (
- ) const
- {
- auto_mutex M(m);
- return ori;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- set_length (
- unsigned long length
- )
- {
- auto_mutex M(m);
- // make the min length be at least 1
- if (length == 0)
- {
- length = 1;
- }
-
-
- parent.invalidate_rectangle(rect);
-
- if (ori == HORIZONTAL)
- {
- rect.set_right(rect.left() + length - 1);
- rect.set_bottom(rect.top() + style->get_width() - 1);
-
- const long btn_size = style->get_button_length(rect.width(), max_pos);
-
- b1.set_size(btn_size,style->get_width());
- b2.set_size(btn_size,style->get_width());
-
- slider.set_size(get_slider_size(),style->get_width());
- }
- else
- {
- rect.set_right(rect.left() + style->get_width() - 1);
- rect.set_bottom(rect.top() + length - 1);
-
- const long btn_size = style->get_button_length(rect.height(), max_pos);
-
- b1.set_size(style->get_width(),btn_size);
- b2.set_size(style->get_width(),btn_size);
-
- slider.set_size(style->get_width(),get_slider_size());
- }
-
- // call this to put everything is in the right spot.
- set_pos (rect.left(),rect.top());
-
- if ((b2.get_rect().top() - b1.get_rect().bottom() - 1 <= 8 && ori == VERTICAL) ||
- (b2.get_rect().left() - b1.get_rect().right() - 1 <= 8 && ori == HORIZONTAL) ||
- max_pos == 0)
- {
- hide_slider();
- }
- else if (enabled && !hidden)
- {
- show_slider();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- set_pos (
- long x,
- long y
- )
- {
- auto_mutex M(m);
- drawable::set_pos(x,y);
-
- b1.set_pos(rect.left(),rect.top());
- if (ori == HORIZONTAL)
- {
- // make the b2 button appear at the end of the scroll_bar
- b2.set_pos(rect.right()-b2.get_rect().width() + 1,rect.top());
-
- if (max_pos != 0)
- {
- double range = b2.get_rect().left() - b1.get_rect().right() - slider.get_rect().width() - 1;
- double slider_pos = pos;
- slider_pos /= max_pos;
- slider_pos *= range;
- slider.set_pos(
- static_cast<long>(slider_pos)+rect.left() + b1.get_rect().width(),
- rect.top()
- );
-
- // move the draggable area for the slider to the new location
- rectangle area = rect;
- area.set_left(area.left() + style->get_width());
- area.set_right(area.right() - style->get_width());
- slider.set_draggable_area(area);
-
- }
-
-
- }
- else
- {
- // make the b2 button appear at the end of the scroll_bar
- b2.set_pos(rect.left(), rect.bottom() - b2.get_rect().height() + 1);
-
- if (max_pos != 0)
- {
- double range = b2.get_rect().top() - b1.get_rect().bottom() - slider.get_rect().height() - 1;
- double slider_pos = pos;
- slider_pos /= max_pos;
- slider_pos *= range;
- slider.set_pos(
- rect.left(),
- static_cast<long>(slider_pos) + rect.top() + b1.get_rect().height()
- );
-
- // move the draggable area for the slider to the new location
- rectangle area = rect;
- area.set_top(area.top() + style->get_width());
- area.set_bottom(area.bottom() - style->get_width());
- slider.set_draggable_area(area);
- }
- }
-
- adjust_fillers();
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long scroll_bar::
- get_slider_size (
- ) const
- {
- if (ori == HORIZONTAL)
- return style->get_slider_length(rect.width(),max_pos);
- else
- return style->get_slider_length(rect.height(),max_pos);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- adjust_fillers (
- )
- {
- rectangle top(rect), bottom(rect);
-
- if (ori == HORIZONTAL)
- {
- if (slider.is_hidden())
- {
- top.set_left(b1.get_rect().right()+1);
- top.set_right(b2.get_rect().left()-1);
- bottom.set_left(1);
- bottom.set_right(-1);
- }
- else
- {
- top.set_left(b1.get_rect().right()+1);
- top.set_right(slider.get_rect().left()-1);
- bottom.set_left(slider.get_rect().right()+1);
- bottom.set_right(b2.get_rect().left()-1);
- }
- }
- else
- {
- if (slider.is_hidden())
- {
- top.set_top(b1.get_rect().bottom()+1);
- top.set_bottom(b2.get_rect().top()-1);
- bottom.set_top(1);
- bottom.set_bottom(-1);
- }
- else
- {
- top.set_top(b1.get_rect().bottom()+1);
- top.set_bottom(slider.get_rect().top()-1);
- bottom.set_top(slider.get_rect().bottom()+1);
- bottom.set_bottom(b2.get_rect().top()-1);
- }
- }
-
- top_filler.rect = top;
- bottom_filler.rect = bottom;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- hide_slider (
- )
- {
- rectangle top(rect), bottom(rect);
- slider.hide();
- top_filler.disable();
- bottom_filler.disable();
- bottom_filler.hide();
- if (ori == HORIZONTAL)
- {
- top.set_left(b1.get_rect().right()+1);
- top.set_right(b2.get_rect().left()-1);
- }
- else
- {
- top.set_top(b1.get_rect().bottom()+1);
- top.set_bottom(b2.get_rect().top()-1);
- }
- top_filler.rect = top;
- bottom_filler.rect = bottom;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- show_slider (
- )
- {
- if ((b2.get_rect().top() - b1.get_rect().bottom() - 1 <= 8 && ori == VERTICAL) ||
- (b2.get_rect().left() - b1.get_rect().right() - 1 <= 8 && ori == HORIZONTAL) ||
- max_pos == 0)
- return;
-
- rectangle top(rect), bottom(rect);
- slider.show();
- top_filler.enable();
- bottom_filler.enable();
- bottom_filler.show();
- if (ori == HORIZONTAL)
- {
- top.set_left(b1.get_rect().right()+1);
- top.set_right(slider.get_rect().left()-1);
- bottom.set_left(slider.get_rect().right()+1);
- bottom.set_right(b2.get_rect().left()-1);
- }
- else
- {
- top.set_top(b1.get_rect().bottom()+1);
- top.set_bottom(slider.get_rect().top()-1);
- bottom.set_top(slider.get_rect().bottom()+1);
- bottom.set_bottom(b2.get_rect().top()-1);
- }
- top_filler.rect = top;
- bottom_filler.rect = bottom;
- }
-
-// ----------------------------------------------------------------------------------------
-
- long scroll_bar::
- max_slider_pos (
- ) const
- {
- auto_mutex M(m);
- return max_pos;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- set_max_slider_pos (
- long mpos
- )
- {
- auto_mutex M(m);
- max_pos = mpos;
- if (pos > mpos)
- pos = mpos;
-
- if (ori == HORIZONTAL)
- set_length(rect.width());
- else
- set_length(rect.height());
-
- if (mpos != 0 && enabled)
- {
- b1.enable();
- b2.enable();
- }
- else
- {
- b1.disable();
- b2.disable();
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- set_slider_pos (
- long pos
- )
- {
- auto_mutex M(m);
- if (pos < 0)
- pos = 0;
- if (pos > max_pos)
- pos = max_pos;
-
- this->pos = pos;
-
- // move the slider object to its new position
- set_pos(rect.left(),rect.top());
- }
-
-// ----------------------------------------------------------------------------------------
-
- long scroll_bar::
- slider_pos (
- ) const
- {
- auto_mutex M(m);
- return pos;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- on_slider_drag (
- )
- {
- if (ori == HORIZONTAL)
- {
- double slider_pos = slider.get_rect().left() - b1.get_rect().right() - 1;
- double range = b2.get_rect().left() - b1.get_rect().right() - slider.get_rect().width() - 1;
- slider_pos /= range;
- slider_pos *= max_pos;
- pos = static_cast<unsigned long>(slider_pos);
- }
- else
- {
- double slider_pos = slider.get_rect().top() - b1.get_rect().bottom() - 1;
- double range = b2.get_rect().top() - b1.get_rect().bottom() - slider.get_rect().height() - 1;
- slider_pos /= range;
- slider_pos *= max_pos;
- pos = static_cast<unsigned long>(slider_pos);
- }
-
- adjust_fillers();
-
- if (scroll_handler.is_set())
- scroll_handler();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- draw (
- const canvas&
- ) const
- {
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- b1_down (
- )
- {
- if (pos != 0)
- {
- set_slider_pos(pos-1);
- if (scroll_handler.is_set())
- scroll_handler();
-
- if (b1_timer.delay_time() == 1000)
- b1_timer.set_delay_time(500);
- else
- b1_timer.set_delay_time(50);
- b1_timer.start();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- b1_up (
- bool
- )
- {
- b1_timer.stop();
- b1_timer.set_delay_time(1000);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- b2_down (
- )
- {
- if (pos != max_pos)
- {
- set_slider_pos(pos+1);
- if (scroll_handler.is_set())
- scroll_handler();
-
- if (b2_timer.delay_time() == 1000)
- b2_timer.set_delay_time(500);
- else
- b2_timer.set_delay_time(50);
- b2_timer.start();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- b2_up (
- bool
- )
- {
- b2_timer.stop();
- b2_timer.set_delay_time(1000);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- top_filler_down (
- )
- {
- // ignore this if the mouse is now outside this object. This could happen
- // since the timers are also calling this function.
- if (top_filler.rect.contains(lastx,lasty) == false)
- {
- top_filler_up(false);
- return;
- }
-
- if (pos != 0)
- {
- if (pos < js)
- {
- // if there is less than jump_size() space left then jump the remaining
- // amount.
- delayed_set_slider_pos(0);
- }
- else
- {
- delayed_set_slider_pos(pos-js);
- }
-
- if (top_filler_timer.delay_time() == 1000)
- top_filler_timer.set_delay_time(500);
- else
- top_filler_timer.set_delay_time(50);
- top_filler_timer.start();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- top_filler_up (
- bool
- )
- {
- top_filler_timer.stop();
- top_filler_timer.set_delay_time(1000);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- bottom_filler_down (
- )
- {
- // ignore this if the mouse is now outside this object. This could happen
- // since the timers are also calling this function.
- if (bottom_filler.rect.contains(lastx,lasty) == false)
- {
- bottom_filler_up(false);
- return;
- }
-
- if (pos != max_pos)
- {
- if (max_pos - pos < js)
- {
- // if there is less than jump_size() space left then jump the remaining
- // amount.
- delayed_set_slider_pos(max_pos);
- }
- else
- {
- delayed_set_slider_pos(pos+js);
- }
-
- if (bottom_filler_timer.delay_time() == 1000)
- bottom_filler_timer.set_delay_time(500);
- else
- bottom_filler_timer.set_delay_time(50);
- bottom_filler_timer.start();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- bottom_filler_up (
- bool
- )
- {
- bottom_filler_timer.stop();
- bottom_filler_timer.set_delay_time(1000);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- set_jump_size (
- long js_
- )
- {
- auto_mutex M(m);
- if (js_ < 1)
- js = 1;
- else
- js = js_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- long scroll_bar::
- jump_size (
- ) const
- {
- auto_mutex M(m);
- return js;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- on_user_event (
- int i
- )
- {
- switch (i)
- {
- case 0:
- b1_down();
- break;
- case 1:
- b2_down();
- break;
- case 2:
- top_filler_down();
- break;
- case 3:
- bottom_filler_down();
- break;
- case 4:
- // if the position we are supposed to switch the slider too isn't
- // already set
- if (delayed_pos != pos)
- {
- set_slider_pos(delayed_pos);
- if (scroll_handler.is_set())
- scroll_handler();
- }
- break;
- default:
- break;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- delayed_set_slider_pos (
- unsigned long dpos
- )
- {
- delayed_pos = dpos;
- parent.trigger_user_event(this,4);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- b1_down_t (
- )
- {
- parent.trigger_user_event(this,0);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- b2_down_t (
- )
- {
- parent.trigger_user_event(this,1);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- top_filler_down_t (
- )
- {
- parent.trigger_user_event(this,2);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar::
- bottom_filler_down_t (
- )
- {
- parent.trigger_user_event(this,3);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// widget_group object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- empty (
- )
- {
- auto_mutex M(m);
- widgets.clear();
- wg_widgets.clear();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- add (
- drawable& widget,
- unsigned long x,
- unsigned long y
- )
- {
- auto_mutex M(m);
- drawable* w = &widget;
- relpos rp;
- rp.x = x;
- rp.y = y;
- if (widgets.is_in_domain(w))
- {
- widgets[w].x = x;
- widgets[w].y = y;
- }
- else
- {
- widgets.add(w,rp);
- }
- if (is_hidden())
- widget.hide();
- else
- widget.show();
-
- if (is_enabled())
- widget.enable();
- else
- widget.disable();
-
- widget.set_z_order(z_order());
- widget.set_pos(x+rect.left(),y+rect.top());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- add (
- widget_group& widget,
- unsigned long x,
- unsigned long y
- )
- {
- auto_mutex M(m);
- drawable& w = widget;
- add(w, x, y);
-
- widget_group* wg = &widget;
- wg_widgets.add(wg);
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool widget_group::
- is_member (
- const drawable& widget
- ) const
- {
- auto_mutex M(m);
- drawable* w = const_cast<drawable*>(&widget);
- return widgets.is_in_domain(w);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- remove (
- const drawable& widget
- )
- {
- auto_mutex M(m);
- drawable* w = const_cast<drawable*>(&widget);
- if (widgets.is_in_domain(w))
- {
- widgets.destroy(w);
-
- // check if we also have an entry in the wg_widgets set and if
- // so then remove that too
- widget_group* wg = reinterpret_cast<widget_group*>(w);
- if (wg_widgets.is_member(wg))
- {
- wg_widgets.destroy(wg);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- size_t widget_group::
- size (
- ) const
- {
- auto_mutex M(m);
- return widgets.size();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- set_pos (
- long x,
- long y
- )
- {
- auto_mutex M(m);
- widgets.reset();
- while (widgets.move_next())
- {
- const unsigned long rx = widgets.element().value().x;
- const unsigned long ry = widgets.element().value().y;
- widgets.element().key()->set_pos(x+rx,y+ry);
- }
- drawable::set_pos(x,y);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- set_z_order (
- long order
- )
- {
- auto_mutex M(m);
- widgets.reset();
- while (widgets.move_next())
- widgets.element().key()->set_z_order(order);
- drawable::set_z_order(order);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- show (
- )
- {
- auto_mutex M(m);
- widgets.reset();
- while (widgets.move_next())
- widgets.element().key()->show();
- drawable::show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- hide (
- )
- {
- auto_mutex M(m);
- widgets.reset();
- while (widgets.move_next())
- widgets.element().key()->hide();
- drawable::hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- enable (
- )
- {
- auto_mutex M(m);
- widgets.reset();
- while (widgets.move_next())
- widgets.element().key()->enable();
- drawable::enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- disable ()
- {
- auto_mutex M(m);
- widgets.reset();
- while (widgets.move_next())
- widgets.element().key()->disable();
- drawable::disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void widget_group::
- fit_to_contents (
- )
- {
- auto_mutex M(m);
-
- // call fit_to_contents on all the widget_groups we contain
- wg_widgets.reset();
- while (wg_widgets.move_next())
- wg_widgets.element()->fit_to_contents();
-
- // now accumulate a rectangle that contains everything in this widget_group
- rectangle r;
- widgets.reset();
- while (widgets.move_next())
- r = r + widgets.element().key()->get_rect();
-
- if (r.is_empty())
- {
- // make sure it is still empty after we set it at the correct position
- r.set_right(rect.left()-1);
- r.set_bottom(rect.top()-1);
- }
-
- r.set_left(rect.left());
- r.set_top(rect.top());
- rect = r;
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// class popup_menu
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- popup_menu::
- popup_menu (
- ) :
- base_window(false,true),
- pad(2),
- item_pad(3),
- cur_rect(pad,pad,pad-1,pad-1),
- left_width(0),
- middle_width(0),
- selected_item(0),
- submenu_open(false)
- {
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- enable_menu_item (
- unsigned long idx
- )
- {
- DLIB_ASSERT ( idx < size() ,
- "\tvoid popup_menu::enable_menu_item()"
- << "\n\tidx: " << idx
- << "\n\tsize(): " << size()
- );
- auto_mutex M(wm);
- item_enabled[idx] = true;
- invalidate_rectangle(cur_rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- disable_menu_item (
- unsigned long idx
- )
- {
- DLIB_ASSERT ( idx < size() ,
- "\tvoid popup_menu::enable_menu_item()"
- << "\n\tidx: " << idx
- << "\n\tsize(): " << size()
- );
- auto_mutex M(wm);
- item_enabled[idx] = false;
- invalidate_rectangle(cur_rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- size_t popup_menu::
- size (
- ) const
- {
- auto_mutex M(wm);
- return items.size();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- clear (
- )
- {
- auto_mutex M(wm);
- hide();
- cur_rect = rectangle(pad,pad,pad-1,pad-1);
- win_rect = rectangle();
- left_width = 0;
- middle_width = 0;
- items.clear();
- item_enabled.clear();
- left_rects.clear();
- middle_rects.clear();
- right_rects.clear();
- line_rects.clear();
- submenus.clear();
- selected_item = 0;
- submenu_open = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- show (
- )
- {
- auto_mutex M(wm);
- selected_item = submenus.size();
- base_window::show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- hide (
- )
- {
- auto_mutex M(wm);
- // hide ourselves
- close_submenu();
- selected_item = submenus.size();
- base_window::hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- select_first_item (
- )
- {
- auto_mutex M(wm);
- close_submenu();
- selected_item = items.size();
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- if ((items[i]->has_click_event() || submenus[i]) && item_enabled[i])
- {
- selected_item = i;
- break;
- }
- }
- invalidate_rectangle(cur_rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool popup_menu::
- forwarded_on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- )
- {
- auto_mutex M(wm);
- // do nothing if this popup menu is empty
- if (items.size() == 0)
- return false;
-
-
- // check if the selected item is a submenu
- if (selected_item != submenus.size() && submenus[selected_item] != 0 && submenu_open)
- {
- // send the key to the submenu and return if that menu used the key
- if (submenus[selected_item]->forwarded_on_keydown(key,is_printable,state) == true)
- return true;
- }
-
- if (key == KEY_UP)
- {
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- selected_item = (selected_item + items.size() - 1)%items.size();
- // only stop looking if this one is enabled and has a click event or is a submenu
- if (item_enabled[selected_item] && (items[selected_item]->has_click_event() || submenus[selected_item]) )
- break;
- }
- invalidate_rectangle(cur_rect);
- return true;
- }
- else if (key == KEY_DOWN)
- {
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- selected_item = (selected_item + 1)%items.size();
- // only stop looking if this one is enabled and has a click event or is a submenu
- if (item_enabled[selected_item] && (items[selected_item]->has_click_event() || submenus[selected_item]))
- break;
- }
- invalidate_rectangle(cur_rect);
- return true;
- }
- else if (key == KEY_RIGHT && submenu_open == false && display_selected_submenu())
- {
- submenus[selected_item]->select_first_item();
- return true;
- }
- else if (key == KEY_LEFT && selected_item != submenus.size() &&
- submenus[selected_item] != 0 && submenu_open)
- {
- close_submenu();
- return true;
- }
- else if (key == '\n')
- {
- if (selected_item != submenus.size() && (items[selected_item]->has_click_event() || submenus[selected_item]))
- {
- const long idx = selected_item;
- // only hide this popup window if this isn't a submenu
- if (submenus[idx] == 0)
- {
- hide();
- hide_handlers.reset();
- while (hide_handlers.move_next())
- hide_handlers.element()();
- }
- else
- {
- display_selected_submenu();
- submenus[idx]->select_first_item();
- }
- items[idx]->on_click();
- return true;
- }
- }
- else if (is_printable)
- {
- // check if there is a hotkey for this key
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- if (std::tolower(key) == std::tolower(items[i]->get_hot_key()) &&
- (items[i]->has_click_event() || submenus[i]) && item_enabled[i] )
- {
- // only hide this popup window if this isn't a submenu
- if (submenus[i] == 0)
- {
- hide();
- hide_handlers.reset();
- while (hide_handlers.move_next())
- hide_handlers.element()();
- }
- else
- {
- if (selected_item != items.size())
- invalidate_rectangle(line_rects[selected_item]);
-
- selected_item = i;
- display_selected_submenu();
- invalidate_rectangle(line_rects[i]);
- submenus[i]->select_first_item();
- }
- items[i]->on_click();
- }
- }
-
- // always say we use a printable key for hotkeys
- return true;
- }
-
- return false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- on_submenu_hide (
- )
- {
- hide();
- hide_handlers.reset();
- while (hide_handlers.move_next())
- hide_handlers.element()();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- on_window_resized(
- )
- {
- invalidate_rectangle(win_rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- on_mouse_up (
- unsigned long btn,
- unsigned long,
- long x,
- long y
- )
- {
- if (cur_rect.contains(x,y) && btn == LEFT)
- {
- // figure out which item this was on
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- if (line_rects[i].contains(x,y) && item_enabled[i] && items[i]->has_click_event())
- {
- // only hide this popup window if this isn't a submenu
- if (submenus[i] == 0)
- {
- hide();
- hide_handlers.reset();
- while (hide_handlers.move_next())
- hide_handlers.element()();
- }
- items[i]->on_click();
- break;
- }
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- on_mouse_move (
- unsigned long ,
- long x,
- long y
- )
- {
- if (cur_rect.contains(x,y))
- {
- // check if the mouse is still in the same rect it was in last time
- rectangle last_rect;
- if (selected_item != submenus.size())
- {
- last_rect = line_rects[selected_item];
- }
-
- // if the mouse isn't in the same rectangle any more
- if (last_rect.contains(x,y) == false)
- {
- if (selected_item != submenus.size())
- {
- invalidate_rectangle(last_rect);
- close_submenu();
- selected_item = submenus.size();
- }
-
-
- // figure out if we should redraw any menu items
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- if (items[i]->has_click_event() || submenus[i])
- {
- if (line_rects[i].contains(x,y))
- {
- selected_item = i;
- break;
- }
- }
- }
-
- // if we found a rectangle that contains the mouse then
- // tell it to redraw itself
- if (selected_item != submenus.size())
- {
- display_selected_submenu();
- invalidate_rectangle(line_rects[selected_item]);
- }
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- close_submenu (
- )
- {
- if (selected_item != submenus.size() && submenus[selected_item] && submenu_open)
- {
- submenus[selected_item]->hide();
- submenu_open = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool popup_menu::
- display_selected_submenu (
- )
- {
- // show the submenu if one exists
- if (selected_item != submenus.size() && submenus[selected_item])
- {
- long wx, wy;
- get_pos(wx,wy);
- wx += line_rects[selected_item].right();
- wy += line_rects[selected_item].top();
- submenus[selected_item]->set_pos(wx+1,wy-2);
- submenus[selected_item]->show();
- submenu_open = true;
- return true;
- }
- return false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- on_mouse_leave (
- )
- {
- if (selected_item != submenus.size())
- {
- // only unhighlight a menu item if it isn't a submenu item
- if (submenus[selected_item] == 0)
- {
- invalidate_rectangle(line_rects[selected_item]);
- selected_item = submenus.size();
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu::
- paint (
- const canvas& c
- )
- {
- c.fill(200,200,200);
- draw_rectangle(c, win_rect);
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- bool is_selected = false;
- if (selected_item != submenus.size() && i == selected_item &&
- item_enabled[i])
- is_selected = true;
-
- items[i]->draw_background(c,line_rects[i], item_enabled[i], is_selected);
- items[i]->draw_left(c,left_rects[i], item_enabled[i], is_selected);
- items[i]->draw_middle(c,middle_rects[i], item_enabled[i], is_selected);
- items[i]->draw_right(c,right_rects[i], item_enabled[i], is_selected);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// class zoomable_region
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- zoomable_region::
- zoomable_region (
- drawable_window& w,
- unsigned long events
- ) :
- drawable(w,MOUSE_CLICK | MOUSE_WHEEL | MOUSE_MOVE | events),
- min_scale(0.15),
- max_scale(1.0),
- zoom_increment_(0.90),
- vsb(w, scroll_bar::VERTICAL),
- hsb(w, scroll_bar::HORIZONTAL)
- {
- scale = 1;
- mouse_drag_screen = false;
- style.reset(new scrollable_region_style_default());
-
- hsb.set_scroll_handler(*this,&zoomable_region::on_h_scroll);
- vsb.set_scroll_handler(*this,&zoomable_region::on_v_scroll);
- }
-
-// ----------------------------------------------------------------------------------------
-
- zoomable_region::
- ~zoomable_region()
- {
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- set_pos (
- long x,
- long y
- )
- {
- auto_mutex M(m);
- drawable::set_pos(x,y);
- const long border_size = style->get_border_size();
- vsb.set_pos(rect.right()-border_size+1-vsb.width(),rect.top()+border_size);
- hsb.set_pos(rect.left()+border_size,rect.bottom()-border_size+1-hsb.height());
-
- display_rect_ = rectangle(rect.left()+border_size,
- rect.top()+border_size,
- rect.right()-border_size-vsb.width(),
- rect.bottom()-border_size-hsb.height());
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- set_zoom_increment (
- double zi
- )
- {
- DLIB_ASSERT(0.0 < zi && zi < 1.0,
- "\tvoid zoomable_region::set_zoom_increment(zi)"
- << "\n\t the zoom increment must be between 0 and 1"
- << "\n\t zi: " << zi
- << "\n\t this: " << this
- );
-
- auto_mutex M(m);
- zoom_increment_ = zi;
- }
-
-// ----------------------------------------------------------------------------------------
-
- double zoomable_region::
- zoom_increment (
- ) const
- {
- auto_mutex M(m);
- return zoom_increment_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- set_max_zoom_scale (
- double ms
- )
- {
- DLIB_ASSERT(ms > 0,
- "\tvoid zoomable_region::set_max_zoom_scale(ms)"
- << "\n\t the max zoom scale must be greater than 0"
- << "\n\t ms: " << ms
- << "\n\t this: " << this
- );
-
- auto_mutex M(m);
- max_scale = ms;
- if (scale > ms)
- {
- scale = max_scale;
- lr_point = gui_to_graph_space(point(display_rect_.right(),display_rect_.bottom()));
- redraw_graph();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- set_min_zoom_scale (
- double ms
- )
- {
- DLIB_ASSERT(ms > 0,
- "\tvoid zoomable_region::set_min_zoom_scale(ms)"
- << "\n\t the min zoom scale must be greater than 0"
- << "\n\t ms: " << ms
- << "\n\t this: " << this
- );
-
- auto_mutex M(m);
- min_scale = ms;
-
- if (scale < ms)
- {
- scale = min_scale;
- }
-
- // just call set_size so that everything gets redrawn right
- set_size(rect.width(), rect.height());
- }
-
-// ----------------------------------------------------------------------------------------
-
- double zoomable_region::
- min_zoom_scale (
- ) const
- {
- auto_mutex M(m);
- return min_scale;
- }
-
-// ----------------------------------------------------------------------------------------
-
- double zoomable_region::
- max_zoom_scale (
- ) const
- {
- auto_mutex M(m);
- return max_scale;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- rectangle old(rect);
- const long border_size = style->get_border_size();
- rect = resize_rect(rect,width,height);
- vsb.set_pos(rect.right()-border_size+1-vsb.width(), rect.top()+border_size);
- hsb.set_pos(rect.left()+border_size, rect.bottom()-border_size+1-hsb.height());
-
- display_rect_ = rectangle(rect.left()+border_size,
- rect.top()+border_size,
- rect.right()-border_size-vsb.width(),
- rect.bottom()-border_size-hsb.height());
- vsb.set_length(display_rect_.height());
- hsb.set_length(display_rect_.width());
- parent.invalidate_rectangle(rect+old);
-
- const double old_scale = scale;
- const vector<double,2> old_gr_orig(gr_orig);
- scale = min_scale;
- gr_orig = vector<double,2>(0,0);
- lr_point = gui_to_graph_space(point(display_rect_.right(),display_rect_.bottom()));
- scale = old_scale;
-
- // call adjust_origin() so that the scroll bars get their max slider positions
- // setup right
- const point rect_corner(display_rect_.left(), display_rect_.top());
- adjust_origin(rect_corner, old_gr_orig);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- show (
- )
- {
- auto_mutex M(m);
- drawable::show();
- hsb.show();
- vsb.show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- hide (
- )
- {
- auto_mutex M(m);
- drawable::hide();
- hsb.hide();
- vsb.hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- enable (
- )
- {
- auto_mutex M(m);
- drawable::enable();
- hsb.enable();
- vsb.enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- disable (
- )
- {
- auto_mutex M(m);
- drawable::disable();
- hsb.disable();
- vsb.disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- set_z_order (
- long order
- )
- {
- auto_mutex M(m);
- drawable::set_z_order(order);
- hsb.set_z_order(order);
- vsb.set_z_order(order);
- }
-
-// ----------------------------------------------------------------------------------------
-
- point zoomable_region::
- graph_to_gui_space (
- const vector<double,2>& p
- ) const
- {
- const point rect_corner(display_rect_.left(), display_rect_.top());
- return (p - gr_orig)*scale + rect_corner;
- }
-
-// ----------------------------------------------------------------------------------------
-
- vector<double,2> zoomable_region::
- gui_to_graph_space (
- const point& p
- ) const
- {
- const point rect_corner(display_rect_.left(), display_rect_.top());
- return (p - rect_corner)/scale + gr_orig;
- }
-
-// ----------------------------------------------------------------------------------------
-
- point zoomable_region::
- max_graph_point (
- ) const
- {
- return lr_point;
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle zoomable_region::
- display_rect (
- ) const
- {
- return display_rect_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- double zoomable_region::
- zoom_scale (
- ) const
- {
- return scale;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- set_zoom_scale (
- double new_scale
- )
- {
- // if new_scale isn't in the right range then put it back in range before we do the
- // rest of this function
- if (!(min_scale <= new_scale && new_scale <= max_scale))
- {
- if (new_scale > max_scale)
- new_scale = max_scale;
- else
- new_scale = min_scale;
- }
-
- // find the point in the center of the graph area
- point center((display_rect_.left()+display_rect_.right())/2, (display_rect_.top()+display_rect_.bottom())/2);
- point graph_p(gui_to_graph_space(center));
- scale = new_scale;
- adjust_origin(center, graph_p);
- redraw_graph();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- center_display_at_graph_point (
- const vector<double,2>& p
- )
- {
- // find the point in the center of the graph area
- point center((display_rect_.left()+display_rect_.right())/2, (display_rect_.top()+display_rect_.bottom())/2);
- adjust_origin(center, p);
- redraw_graph();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- on_wheel_down (
- unsigned long
- )
- {
- // zoom out
- if (enabled && !hidden && scale > min_scale && display_rect_.contains(lastx,lasty))
- {
- point gui_p(lastx,lasty);
- point graph_p(gui_to_graph_space(gui_p));
- const double old_scale = scale;
- scale *= zoom_increment_;
- if (scale < min_scale)
- scale = min_scale;
- redraw_graph();
- adjust_origin(gui_p, graph_p);
-
- if (scale != old_scale)
- on_view_changed();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- on_wheel_up (
- unsigned long
- )
- {
- // zoom in
- if (enabled && !hidden && scale < max_scale && display_rect_.contains(lastx,lasty))
- {
- point gui_p(lastx,lasty);
- point graph_p(gui_to_graph_space(gui_p));
- const double old_scale = scale;
- scale /= zoom_increment_;
- if (scale > max_scale)
- scale = max_scale;
- redraw_graph();
- adjust_origin(gui_p, graph_p);
-
- if (scale != old_scale)
- on_view_changed();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- if (enabled && !hidden && mouse_drag_screen)
- {
- adjust_origin(point(x,y), drag_screen_point);
- redraw_graph();
- on_view_changed();
- }
-
- // check if the mouse isn't being dragged anymore
- if ((state & base_window::LEFT) == 0)
- {
- mouse_drag_screen = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- on_mouse_up (
- unsigned long ,
- unsigned long ,
- long ,
- long
- )
- {
- mouse_drag_screen = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- )
- {
- if (enabled && !hidden && display_rect_.contains(x,y) && btn == base_window::LEFT)
- {
- mouse_drag_screen = true;
- drag_screen_point = gui_to_graph_space(point(x,y));
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- draw (
- const canvas& c
- ) const
- {
- style->draw_scrollable_region_border(c, rect, enabled);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- on_h_scroll (
- )
- {
- gr_orig.x() = hsb.slider_pos();
- redraw_graph();
-
- on_view_changed();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- on_v_scroll (
- )
- {
- gr_orig.y() = vsb.slider_pos();
- redraw_graph();
-
- on_view_changed();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- redraw_graph (
- )
- {
- parent.invalidate_rectangle(display_rect_);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void zoomable_region::
- adjust_origin (
- const point& gui_p,
- const vector<double,2>& graph_p
- )
- {
- const point rect_corner(display_rect_.left(), display_rect_.top());
- const dlib::vector<double,2> v(gui_p - rect_corner);
- gr_orig = graph_p - v/scale;
-
-
- // make sure the origin isn't outside the point (0,0)
- if (gr_orig.x() < 0)
- gr_orig.x() = 0;
- if (gr_orig.y() < 0)
- gr_orig.y() = 0;
-
- // make sure the lower right corner of the display_rect_ doesn't map to a point beyond lr_point
- point lr_rect_corner(display_rect_.right(), display_rect_.bottom());
- point p = graph_to_gui_space(lr_point);
- vector<double,2> lr_rect_corner_graph_space(gui_to_graph_space(lr_rect_corner));
- vector<double,2> delta(lr_point - lr_rect_corner_graph_space);
- if (lr_rect_corner.x() > p.x())
- {
- gr_orig.x() += delta.x();
- }
-
- if (lr_rect_corner.y() > p.y())
- {
- gr_orig.y() += delta.y();
- }
-
-
- const vector<double,2> ul_rect_corner_graph_space(gui_to_graph_space(rect_corner));
- lr_rect_corner_graph_space = gui_to_graph_space(lr_rect_corner);
- // now adjust the scroll bars
-
- hsb.set_max_slider_pos((unsigned long)std::max(lr_point.x()-(lr_rect_corner_graph_space.x()-ul_rect_corner_graph_space.x()),0.0));
- vsb.set_max_slider_pos((unsigned long)std::max(lr_point.y()-(lr_rect_corner_graph_space.y()-ul_rect_corner_graph_space.y()),0.0));
- // adjust slider position now.
- hsb.set_slider_pos(static_cast<long>(ul_rect_corner_graph_space.x()));
- vsb.set_slider_pos(static_cast<long>(ul_rect_corner_graph_space.y()));
-
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// class scrollable_region
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- scrollable_region::
- scrollable_region (
- drawable_window& w,
- unsigned long events
- ) :
- drawable(w, MOUSE_WHEEL|events|MOUSE_CLICK|MOUSE_MOVE),
- hsb(w,scroll_bar::HORIZONTAL),
- vsb(w,scroll_bar::VERTICAL),
- hscroll_bar_inc(1),
- vscroll_bar_inc(1),
- h_wheel_scroll_bar_inc(1),
- v_wheel_scroll_bar_inc(1),
- mouse_drag_enabled_(false),
- user_is_dragging_mouse(false)
- {
- style.reset(new scrollable_region_style_default());
-
- hsb.set_scroll_handler(*this,&scrollable_region::on_h_scroll);
- vsb.set_scroll_handler(*this,&scrollable_region::on_v_scroll);
- }
-
-// ----------------------------------------------------------------------------------------
-
- scrollable_region::
- ~scrollable_region (
- )
- {
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- show (
- )
- {
- auto_mutex M(m);
- drawable::show();
- if (need_h_scroll())
- hsb.show();
- if (need_v_scroll())
- vsb.show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- hide (
- )
- {
- auto_mutex M(m);
- drawable::hide();
- hsb.hide();
- vsb.hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- enable (
- )
- {
- auto_mutex M(m);
- drawable::enable();
- hsb.enable();
- vsb.enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- disable (
- )
- {
- auto_mutex M(m);
- drawable::disable();
- hsb.disable();
- vsb.disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_z_order (
- long order
- )
- {
- auto_mutex M(m);
- drawable::set_z_order(order);
- hsb.set_z_order(order);
- vsb.set_z_order(order);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- rectangle old(rect);
- rect = resize_rect(rect,width,height);
- vsb.set_pos(rect.right()-style->get_border_size()-vsb.width()+1, rect.top()+style->get_border_size());
- hsb.set_pos(rect.left()+style->get_border_size(), rect.bottom()-style->get_border_size()-hsb.height()+1);
-
- // adjust the display_rect_
- if (need_h_scroll() && need_v_scroll())
- {
- // both scroll bars aren't hidden
- if (!hidden)
- {
- vsb.show();
- hsb.show();
- }
- display_rect_ = rectangle( rect.left()+style->get_border_size(),
- rect.top()+style->get_border_size(),
- rect.right()-style->get_border_size()-vsb.width(),
- rect.bottom()-style->get_border_size()-hsb.height());
-
- // figure out how many scroll bar positions there should be
- unsigned long hdelta = total_rect_.width()-display_rect_.width();
- unsigned long vdelta = total_rect_.height()-display_rect_.height();
- hdelta = (hdelta+hscroll_bar_inc-1)/hscroll_bar_inc;
- vdelta = (vdelta+vscroll_bar_inc-1)/vscroll_bar_inc;
-
- hsb.set_max_slider_pos(hdelta);
- vsb.set_max_slider_pos(vdelta);
-
- vsb.set_jump_size((display_rect_.height()+vscroll_bar_inc-1)/vscroll_bar_inc/2+1);
- hsb.set_jump_size((display_rect_.width()+hscroll_bar_inc-1)/hscroll_bar_inc/2+1);
- }
- else if (need_h_scroll())
- {
- // only hsb is hidden
- if (!hidden)
- {
- hsb.show();
- vsb.hide();
- }
- display_rect_ = rectangle( rect.left()+style->get_border_size(),
- rect.top()+style->get_border_size(),
- rect.right()-style->get_border_size(),
- rect.bottom()-style->get_border_size()-hsb.height());
-
- // figure out how many scroll bar positions there should be
- unsigned long hdelta = total_rect_.width()-display_rect_.width();
- hdelta = (hdelta+hscroll_bar_inc-1)/hscroll_bar_inc;
-
- hsb.set_max_slider_pos(hdelta);
- vsb.set_max_slider_pos(0);
-
- hsb.set_jump_size((display_rect_.width()+hscroll_bar_inc-1)/hscroll_bar_inc/2+1);
- }
- else if (need_v_scroll())
- {
- // only vsb is hidden
- if (!hidden)
- {
- hsb.hide();
- vsb.show();
- }
- display_rect_ = rectangle( rect.left()+style->get_border_size(),
- rect.top()+style->get_border_size(),
- rect.right()-style->get_border_size()-vsb.width(),
- rect.bottom()-style->get_border_size());
-
- unsigned long vdelta = total_rect_.height()-display_rect_.height();
- vdelta = (vdelta+vscroll_bar_inc-1)/vscroll_bar_inc;
-
- hsb.set_max_slider_pos(0);
- vsb.set_max_slider_pos(vdelta);
-
- vsb.set_jump_size((display_rect_.height()+vscroll_bar_inc-1)/vscroll_bar_inc/2+1);
- }
- else
- {
- // both are hidden
- if (!hidden)
- {
- hsb.hide();
- vsb.hide();
- }
- display_rect_ = rectangle( rect.left()+style->get_border_size(),
- rect.top()+style->get_border_size(),
- rect.right()-style->get_border_size(),
- rect.bottom()-style->get_border_size());
-
- hsb.set_max_slider_pos(0);
- vsb.set_max_slider_pos(0);
- }
-
- vsb.set_length(display_rect_.height());
- hsb.set_length(display_rect_.width());
-
- // adjust the total_rect_ position by trigging the scroll events
- on_h_scroll();
- on_v_scroll();
-
- parent.invalidate_rectangle(rect+old);
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long scrollable_region::
- horizontal_mouse_wheel_scroll_increment (
- ) const
- {
- auto_mutex M(m);
- return h_wheel_scroll_bar_inc;
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long scrollable_region::
- vertical_mouse_wheel_scroll_increment (
- ) const
- {
- auto_mutex M(m);
- return v_wheel_scroll_bar_inc;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_horizontal_mouse_wheel_scroll_increment (
- unsigned long inc
- )
- {
- auto_mutex M(m);
- h_wheel_scroll_bar_inc = inc;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_vertical_mouse_wheel_scroll_increment (
- unsigned long inc
- )
- {
- auto_mutex M(m);
- v_wheel_scroll_bar_inc = inc;
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long scrollable_region::
- horizontal_scroll_increment (
- ) const
- {
- auto_mutex M(m);
- return hscroll_bar_inc;
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long scrollable_region::
- vertical_scroll_increment (
- ) const
- {
- auto_mutex M(m);
- return vscroll_bar_inc;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_horizontal_scroll_increment (
- unsigned long inc
- )
- {
- auto_mutex M(m);
- hscroll_bar_inc = inc;
- // call set_size to reset the scroll bars
- set_size(rect.width(),rect.height());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_vertical_scroll_increment (
- unsigned long inc
- )
- {
- auto_mutex M(m);
- vscroll_bar_inc = inc;
- // call set_size to reset the scroll bars
- set_size(rect.width(),rect.height());
- }
-
-// ----------------------------------------------------------------------------------------
-
- long scrollable_region::
- horizontal_scroll_pos (
- ) const
- {
- auto_mutex M(m);
- return hsb.slider_pos();
- }
-
-// ----------------------------------------------------------------------------------------
-
- long scrollable_region::
- vertical_scroll_pos (
- ) const
- {
- auto_mutex M(m);
- return vsb.slider_pos();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_horizontal_scroll_pos (
- long pos
- )
- {
- auto_mutex M(m);
-
- hsb.set_slider_pos(pos);
- on_h_scroll();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_vertical_scroll_pos (
- long pos
- )
- {
- auto_mutex M(m);
-
- vsb.set_slider_pos(pos);
- on_v_scroll();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_pos (
- long x,
- long y
- )
- {
- auto_mutex M(m);
- drawable::set_pos(x,y);
- vsb.set_pos(rect.right()-style->get_border_size()-vsb.width()+1, rect.top()+style->get_border_size());
- hsb.set_pos(rect.left()+style->get_border_size(), rect.bottom()-style->get_border_size()-hsb.height()+1);
-
- const long delta_x = total_rect_.left() - display_rect_.left();
- const long delta_y = total_rect_.top() - display_rect_.top();
-
- display_rect_ = move_rect(display_rect_, rect.left()+style->get_border_size(), rect.top()+style->get_border_size());
-
- total_rect_ = move_rect(total_rect_, display_rect_.left()+delta_x, display_rect_.top()+delta_y);
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool scrollable_region::
- mouse_drag_enabled (
- ) const
- {
- auto_mutex M(m);
- return mouse_drag_enabled_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- enable_mouse_drag (
- )
- {
- auto_mutex M(m);
- mouse_drag_enabled_ = true;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- disable_mouse_drag (
- )
- {
- auto_mutex M(m);
- mouse_drag_enabled_ = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rectangle& scrollable_region::
- display_rect (
- ) const
- {
- return display_rect_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- set_total_rect_size (
- unsigned long width,
- unsigned long height
- )
- {
- DLIB_ASSERT((width > 0 && height > 0) || (width == 0 && height == 0),
- "\tvoid scrollable_region::set_total_rect_size(width,height)"
- << "\n\twidth and height must be > 0 or both == 0"
- << "\n\twidth: " << width
- << "\n\theight: " << height
- << "\n\tthis: " << this
- );
-
- total_rect_ = move_rect(rectangle(width,height),
- display_rect_.left()-static_cast<long>(hsb.slider_pos()),
- display_rect_.top()-static_cast<long>(vsb.slider_pos()));
-
- // call this just to reconfigure the scroll bars
- set_size(rect.width(),rect.height());
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rectangle& scrollable_region::
- total_rect (
- ) const
- {
- return total_rect_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- scroll_to_rect (
- const rectangle& r_
- )
- {
- const rectangle r(total_rect_.intersect(r_));
- const rectangle old(total_rect_);
- // adjust the horizontal scroll bar so that r fits as best as possible
- if (r.left() < display_rect_.left())
- {
- long distance = (r.left()-total_rect_.left())/hscroll_bar_inc;
- hsb.set_slider_pos(distance);
- }
- else if (r.right() > display_rect_.right())
- {
- long distance = (r.right()-total_rect_.left()-display_rect_.width()+hscroll_bar_inc)/hscroll_bar_inc;
- hsb.set_slider_pos(distance);
- }
-
- // adjust the vertical scroll bar so that r fits as best as possible
- if (r.top() < display_rect_.top())
- {
- long distance = (r.top()-total_rect_.top())/vscroll_bar_inc;
- vsb.set_slider_pos(distance);
- }
- else if (r.bottom() > display_rect_.bottom())
- {
- long distance = (r.bottom()-total_rect_.top()-display_rect_.height()+vscroll_bar_inc)/vscroll_bar_inc;
- vsb.set_slider_pos(distance);
- }
-
-
- // adjust total_rect_ so that it matches where the scroll bars are now
- total_rect_ = move_rect(total_rect_,
- display_rect_.left()-hscroll_bar_inc*hsb.slider_pos(),
- display_rect_.top()-vscroll_bar_inc*vsb.slider_pos());
-
- // only redraw if we actually changed something
- if (total_rect_ != old)
- {
- parent.invalidate_rectangle(display_rect_);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- on_wheel_down (
- unsigned long
- )
- {
- if (rect.contains(lastx,lasty) && enabled && !hidden)
- {
- if (need_v_scroll())
- {
- long pos = vsb.slider_pos();
- vsb.set_slider_pos(pos+(long)v_wheel_scroll_bar_inc);
- on_v_scroll();
- }
- else if (need_h_scroll())
- {
- long pos = hsb.slider_pos();
- hsb.set_slider_pos(pos+(long)h_wheel_scroll_bar_inc);
- on_h_scroll();
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- if (enabled && !hidden && user_is_dragging_mouse && state==base_window::LEFT)
- {
- point current_delta = point(x,y) - point(total_rect().left(), total_rect().top());
- rectangle new_rect(translate_rect(display_rect(), drag_origin - current_delta));
- new_rect = centered_rect(new_rect, new_rect.width()-hscroll_bar_inc, new_rect.height()-vscroll_bar_inc);
- scroll_to_rect(new_rect);
- on_view_changed();
- }
- else
- {
- user_is_dragging_mouse = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- )
- {
- if (mouse_drag_enabled_ && enabled && !hidden && display_rect().contains(x,y) && (btn==base_window::LEFT))
- {
- drag_origin = point(x,y) - point(total_rect().left(), total_rect().top());
- user_is_dragging_mouse = true;
- }
- else
- {
- user_is_dragging_mouse = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- on_mouse_up (
- unsigned long ,
- unsigned long ,
- long ,
- long
- )
- {
- user_is_dragging_mouse = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- on_wheel_up (
- unsigned long
- )
- {
- if (rect.contains(lastx,lasty) && enabled && !hidden)
- {
- if (need_v_scroll())
- {
- long pos = vsb.slider_pos();
- vsb.set_slider_pos(pos-(long)v_wheel_scroll_bar_inc);
- on_v_scroll();
- }
- else if (need_h_scroll())
- {
- long pos = hsb.slider_pos();
- hsb.set_slider_pos(pos-(long)h_wheel_scroll_bar_inc);
- on_h_scroll();
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- draw (
- const canvas& c
- ) const
- {
- style->draw_scrollable_region_border(c, rect, enabled);
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool scrollable_region::
- need_h_scroll (
- ) const
- {
- if (total_rect_.width() > rect.width()-style->get_border_size()*2)
- {
- return true;
- }
- else
- {
- // check if we would need a vertical scroll bar and if adding one would make us need
- // a horizontal one
- if (total_rect_.height() > rect.height()-style->get_border_size()*2 &&
- total_rect_.width() > rect.width()-style->get_border_size()*2-vsb.width())
- return true;
- else
- return false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool scrollable_region::
- need_v_scroll (
- ) const
- {
- if (total_rect_.height() > rect.height()-style->get_border_size()*2)
- {
- return true;
- }
- else
- {
- // check if we would need a horizontal scroll bar and if adding one would make us need
- // a vertical_scroll_pos one
- if (total_rect_.width() > rect.width()-style->get_border_size()*2 &&
- total_rect_.height() > rect.height()-style->get_border_size()*2-hsb.height())
- return true;
- else
- return false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- on_h_scroll (
- )
- {
- total_rect_ = move_rect(total_rect_, display_rect_.left()-hscroll_bar_inc*hsb.slider_pos(), total_rect_.top());
- parent.invalidate_rectangle(display_rect_);
- if (events_are_enabled())
- on_view_changed();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scrollable_region::
- on_v_scroll (
- )
- {
- total_rect_ = move_rect(total_rect_, total_rect_.left(), display_rect_.top()-vscroll_bar_inc*vsb.slider_pos());
- parent.invalidate_rectangle(display_rect_);
- if (events_are_enabled())
- on_view_changed();
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// class popup_menu_region
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- popup_menu_region::
- popup_menu_region(
- drawable_window& w
- ) :
- drawable(w,MOUSE_CLICK | KEYBOARD_EVENTS | FOCUS_EVENTS | WINDOW_MOVED),
- popup_menu_shown(false)
- {
-
- menu_.set_on_hide_handler(*this,&popup_menu_region::on_menu_becomes_hidden);
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- popup_menu_region::
- ~popup_menu_region(
- )
- {
- disable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- rect = resize_rect(rect,width,height);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- set_rect (
- const rectangle& new_rect
- )
- {
- auto_mutex M(m);
- rect = new_rect;
- }
-
-// ----------------------------------------------------------------------------------------
-
- popup_menu& popup_menu_region::
- menu (
- )
- {
- return menu_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- hide (
- )
- {
- auto_mutex M(m);
- drawable::hide();
- menu_.hide();
- popup_menu_shown = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- disable (
- )
- {
- auto_mutex M(m);
- drawable::disable();
- menu_.hide();
- popup_menu_shown = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- )
- {
- if (enabled && !hidden && popup_menu_shown)
- {
- menu_.forwarded_on_keydown(key, is_printable, state);
- }
- else if (popup_menu_shown)
- {
- menu_.hide();
- popup_menu_shown = false;
- }
-
- if (key == (unsigned long)base_window::KEY_ESC)
- {
- menu_.hide();
- popup_menu_shown = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- on_menu_becomes_hidden (
- )
- {
- popup_menu_shown = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- on_focus_lost (
- )
- {
- if (popup_menu_shown)
- {
- menu_.hide();
- popup_menu_shown = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- on_focus_gained (
- )
- {
- if (popup_menu_shown)
- {
- menu_.hide();
- popup_menu_shown = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- on_window_moved(
- )
- {
- if (popup_menu_shown)
- {
- menu_.hide();
- popup_menu_shown = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- )
- {
- if (enabled && !hidden && rect.contains(x,y) && btn == base_window::RIGHT)
- {
- long orig_x, orig_y;
- parent.get_pos(orig_x, orig_y);
- menu_.set_pos(orig_x+x, orig_y+y);
- menu_.show();
- popup_menu_shown = true;
- }
- else if (popup_menu_shown)
- {
- menu_.hide();
- popup_menu_shown = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void popup_menu_region::
- draw (
- const canvas&
- ) const
- {
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_BASE_WIDGETs_CPP_
-
diff --git a/ml/dlib/dlib/gui_widgets/base_widgets.h b/ml/dlib/dlib/gui_widgets/base_widgets.h
deleted file mode 100644
index 7c6d25097..000000000
--- a/ml/dlib/dlib/gui_widgets/base_widgets.h
+++ /dev/null
@@ -1,2678 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-
-#ifndef DLIB_BASE_WIDGETs_
-#define DLIB_BASE_WIDGETs_
-
-#include <cctype>
-#include <memory>
-
-#include "base_widgets_abstract.h"
-#include "drawable.h"
-#include "../gui_core.h"
-#include "../algs.h"
-#include "../member_function_pointer.h"
-#include "../timer.h"
-#include "../map.h"
-#include "../set.h"
-#include "../array2d.h"
-#include "../pixel.h"
-#include "../image_transforms/assign_image.h"
-#include "../array.h"
-#include "style.h"
-#include "../unicode.h"
-#include "../any.h"
-
-
-namespace dlib
-{
-
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class draggable
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class draggable : public drawable
- {
- /*!
- INITIAL VALUE
- - drag == false
-
- CONVENTION
- - if (the user is holding the left button down over this object) then
- - drag == true
- - x == the x position of the mouse relative to the upper left corner
- of this object.
- - y == the y position of the mouse relative to the upper left corner
- of this object.
- - else
- - drag == false
- !*/
-
- public:
-
- draggable(
- drawable_window& w,
- unsigned long events = 0
- ) :
- drawable(w,events | MOUSE_MOVE | MOUSE_CLICK),
- drag(false)
- {}
-
- virtual ~draggable(
- ) = 0;
-
- rectangle draggable_area (
- ) const { auto_mutex M(m); return area; }
-
- void set_draggable_area (
- const rectangle& area_
- ) { auto_mutex M(m); area = area_; }
-
- protected:
-
- bool is_being_dragged (
- ) const { return drag; }
-
- virtual void on_drag (
- ){}
-
- virtual void on_drag_stop (
- ){}
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- );
-
- private:
-
- rectangle area;
- bool drag;
- long x, y;
-
- // restricted functions
- draggable(draggable&); // copy constructor
- draggable& operator=(draggable&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class mouse_over_event
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class mouse_over_event : public drawable
- {
- /*!
- INITIAL VALUE
- - is_mouse_over_ == false
-
- CONVENTION
- - is_mouse_over_ == is_mouse_over()
- !*/
-
- public:
-
- mouse_over_event(
- drawable_window& w,
- unsigned long events = 0
- ) :
- drawable(w,events | MOUSE_MOVE),
- is_mouse_over_(false)
- {}
-
-
- virtual ~mouse_over_event(
- ) = 0;
-
- int next_free_user_event_number() const
- {
- return drawable::next_free_user_event_number()+1;
- }
-
- protected:
-
- bool is_mouse_over (
- ) const;
-
- virtual void on_mouse_over (
- ){}
-
- virtual void on_mouse_not_over (
- ){}
-
- void on_mouse_leave (
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_user_event (
- int num
- );
-
- private:
- mutable bool is_mouse_over_;
-
- // restricted functions
- mouse_over_event(mouse_over_event&); // copy constructor
- mouse_over_event& operator=(mouse_over_event&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class button_action
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class button_action : public mouse_over_event
- {
- /*!
- INITIAL VALUE
- - is_depressed_ == false
- - seen_click == false
-
- CONVENTION
- - is_depressed_ == is_depressed()
- - if (the user has clicked the button but hasn't yet released the
- left mouse button) then
- - seen_click == true
- - else
- - seen_click == false
- !*/
-
- public:
-
- button_action(
- drawable_window& w,
- unsigned long events = 0
- ) :
- mouse_over_event(w,events | MOUSE_MOVE | MOUSE_CLICK),
- is_depressed_(false),
- seen_click(false)
- {}
-
-
- virtual ~button_action(
- ) = 0;
-
- int next_free_user_event_number() const
- {
- return mouse_over_event::next_free_user_event_number()+1;
- }
-
- protected:
-
- bool is_depressed (
- ) const;
-
- virtual void on_button_down (
- ){}
-
- virtual void on_button_up (
- bool
- ){}
-
- void on_mouse_not_over (
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long,
- long x,
- long y
- );
-
-
- private:
- mutable bool is_depressed_;
- bool seen_click;
-
- void on_user_event (
- int num
- );
-
- // restricted functions
- button_action(button_action&); // copy constructor
- button_action& operator=(button_action&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class widget_group
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class widget_group : public drawable
- {
- /*!
- INITIAL VALUE
- widgets.size() == 0
-
- CONVENTION
- - widgets contains all the drawable objects and their relative positions
- that are in *this.
- - wg_widgets contains pointers to just the widgets that happen
- to be widget_group objects.
- !*/
-
- struct relpos
- {
- unsigned long x;
- unsigned long y;
- };
-
- public:
- widget_group(
- drawable_window& w
- ) : drawable(w) { rect = rectangle(0,0,-1,-1); enable_events();}
-
- virtual ~widget_group(
- ){ disable_events(); }
-
- void empty (
- );
-
- void add (
- drawable& widget,
- unsigned long x,
- unsigned long y
- );
-
- void add (
- widget_group& widget,
- unsigned long x,
- unsigned long y
- );
-
- bool is_member (
- const drawable& widget
- ) const;
-
- void remove (
- const drawable& widget
- );
-
- size_t size (
- ) const;
-
- void set_pos (
- long x,
- long y
- );
-
- void set_z_order (
- long order
- );
-
- void show (
- );
-
- void hide (
- );
-
- void enable (
- );
-
- void disable (
- );
-
- void fit_to_contents (
- );
-
- protected:
-
- // this object doesn't draw anything but also isn't abstract
- void draw (
- const canvas&
- ) const {}
-
- private:
-
- map<drawable*,relpos>::kernel_1a_c widgets;
- set<widget_group*>::kernel_1a_c wg_widgets;
-
-
- // restricted functions
- widget_group(widget_group&); // copy constructor
- widget_group& operator=(widget_group&); // assignment operator
- };
-
-
-// ----------------------------------------------------------------------------------------
-
- class image_widget : public draggable
- {
- /*!
- INITIAL VALUE
- - img.size() == 0
-
- CONVENTION
- - img == the image this object displays
- !*/
-
- public:
-
- image_widget(
- drawable_window& w
- ): draggable(w) { enable_events(); }
-
- ~image_widget(
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- }
-
- template <
- typename image_type
- >
- void set_image (
- const image_type& new_img
- )
- {
- auto_mutex M(m);
- assign_image_scaled(img,new_img);
- rectangle old(rect);
- rect.set_right(rect.left()+num_columns(img)-1);
- rect.set_bottom(rect.top()+num_rows(img)-1);
- parent.invalidate_rectangle(rect+old);
- }
-
- private:
-
- void draw (
- const canvas& c
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- draw_image(c, point(rect.left(),rect.top()), img);
- }
-
- array2d<rgb_alpha_pixel> img;
-
- // restricted functions
- image_widget(image_widget&); // copy constructor
- image_widget& operator=(image_widget&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class tooltip
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class tooltip : public mouse_over_event
- {
- /*!
- INITIAL VALUE
- - stuff.get() == 0
- - events_are_enabled() == false
-
- CONVENTION
- - if (events_are_enabled() == true) then
- - stuff.get() != 0
- !*/
-
- public:
-
- tooltip(
- drawable_window& w
- ) :
- mouse_over_event(w,MOUSE_CLICK)
- {}
-
- ~tooltip(
- ){ disable_events();}
-
- void set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- rect = resize_rect(rect,width,height);
- }
-
-
- void set_text (
- const std::string& str
- )
- {
- set_text(convert_mbstring_to_wstring(str));
- }
-
- void set_text (
- const std::wstring& str
- )
- {
- set_text(convert_wstring_to_utf32(str));
- }
-
- void set_text (
- const ustring& str
- )
- {
- auto_mutex M(m);
- if (!stuff)
- {
- stuff.reset(new data(*this));
- enable_events();
- }
-
- stuff->win.set_text(str);
- }
-
- const std::string text (
- ) const
- {
- return convert_wstring_to_mbstring(wtext());
- }
-
- const std::wstring wtext (
- ) const
- {
- return convert_utf32_to_wstring(utext());
- }
-
- const dlib::ustring utext (
- ) const
- {
- auto_mutex M(m);
- dlib::ustring temp;
- if (stuff)
- {
- temp = stuff->win.text;
- }
- return temp.c_str();
- }
-
- void hide (
- )
- {
- auto_mutex M(m);
- mouse_over_event::hide();
- if (stuff)
- {
- stuff->tt_timer.stop();
- stuff->win.hide();
- }
- }
-
- void disable (
- )
- {
- auto_mutex M(m);
- mouse_over_event::disable();
- if (stuff)
- {
- stuff->tt_timer.stop();
- stuff->win.hide();
- }
- }
-
- protected:
-
- void on_mouse_over()
- {
- stuff->x = lastx;
- stuff->y = lasty;
- stuff->tt_timer.start();
- }
-
- void on_mouse_not_over ()
- {
- stuff->tt_timer.stop();
- stuff->win.hide();
- }
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- )
- {
- mouse_over_event::on_mouse_down(btn,state,x,y,is_double_click);
- stuff->tt_timer.stop();
- stuff->win.hide();
- }
-
- void draw (
- const canvas&
- ) const{}
-
- private:
-
- class tooltip_window : public base_window
- {
- public:
- tooltip_window (const std::shared_ptr<font>& f) : base_window(false,true), pad(3), mfont(f)
- {
- }
-
- ustring text;
- rectangle rect_all;
- rectangle rect_text;
- const unsigned long pad;
- const std::shared_ptr<font> mfont;
-
- void set_text (
- const std::string& str
- )
- {
- set_text(convert_mbstring_to_wstring(str));
- }
-
- void set_text (
- const std::wstring& str
- )
- {
- set_text(convert_wstring_to_utf32(str));
- }
-
- void set_text (
- const dlib::ustring& str
- )
- {
- text = str.c_str();
-
- unsigned long width, height;
- mfont->compute_size(text,width,height);
-
- set_size(width+pad*2, height+pad*2);
- rect_all.set_left(0);
- rect_all.set_top(0);
- rect_all.set_right(width+pad*2-1);
- rect_all.set_bottom(height+pad*2-1);
-
- rect_text = move_rect(rectangle(width,height),pad,pad);
- }
-
- void paint(const canvas& c)
- {
- c.fill(255,255,150);
- draw_rectangle(c, rect_all);
- mfont->draw_string(c,rect_text,text);
- }
- };
-
- void show_tooltip (
- )
- {
- auto_mutex M(m);
- long x, y;
- // if the mouse has moved since we started the timer then
- // keep waiting until the user stops moving it
- if (lastx != stuff->x || lasty != stuff->y)
- {
- stuff->x = lastx;
- stuff->y = lasty;
- return;
- }
-
- unsigned long display_width, display_height;
- // stop the timer
- stuff->tt_timer.stop();
- parent.get_pos(x,y);
- x += lastx+15;
- y += lasty+15;
-
- // make sure the tooltip isn't going to be off the screen
- parent.get_display_size(display_width, display_height);
- rectangle wrect(move_rect(stuff->win.rect_all,x,y));
- rectangle srect(display_width, display_height);
- if (srect.contains(wrect) == false)
- {
- rectangle temp(srect.intersect(wrect));
- x -= wrect.width()-temp.width();
- y -= wrect.height()-temp.height();
- }
-
- stuff->win.set_pos(x,y);
- stuff->win.show();
- }
-
- // put all this stuff in data so we can arrange to only
- // construct it when someone is actually using the tooltip widget
- // rather than just instantiating it.
- struct data
- {
- data(
- tooltip& self
- ) :
- x(-1),
- y(-1),
- win(self.mfont),
- tt_timer(self,&tooltip::show_tooltip)
- {
- tt_timer.set_delay_time(400);
- }
-
- long x, y;
- tooltip_window win;
- timer<tooltip> tt_timer;
-
- };
- friend struct data;
- std::unique_ptr<data> stuff;
-
-
-
- // restricted functions
- tooltip(tooltip&); // copy constructor
- tooltip& operator=(tooltip&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class button
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class button : public button_action
- {
- public:
- button(
- drawable_window& w
- ) :
- button_action(w),
- btn_tooltip(w)
- {
- style.reset(new button_style_default());
- enable_events();
- }
-
- ~button() { disable_events(); parent.invalidate_rectangle(style->get_invalidation_rect(rect)); }
-
- void set_size (
- unsigned long width,
- unsigned long height
- );
-
- void set_name (
- const std::string& name_
- );
-
- void set_name (
- const std::wstring& name_
- );
-
- void set_name (
- const dlib::ustring& name_
- );
-
- const std::string name (
- ) const;
-
- const std::wstring wname (
- ) const;
-
- const dlib::ustring uname (
- ) const;
-
- void set_tooltip_text (
- const std::string& text
- );
-
- void set_tooltip_text (
- const std::wstring& text
- );
-
- void set_tooltip_text (
- const dlib::ustring& text
- );
-
- void set_pos(
- long x,
- long y
- );
-
- const std::string tooltip_text (
- ) const;
-
- const std::wstring tooltip_wtext (
- ) const;
-
- const dlib::ustring tooltip_utext (
- ) const;
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- void show (
- );
-
- void hide (
- );
-
- void enable (
- );
-
- void disable (
- );
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- )
- {
- auto_mutex M(m);
- style.reset(new style_type(style_));
- rect = move_rect(style->get_min_size(name_,*mfont), rect.left(), rect.top());
- parent.invalidate_rectangle(style->get_invalidation_rect(rect));
- }
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler_)()
- )
- {
- auto_mutex M(m);
- event_handler = make_mfp(object,event_handler_);
- event_handler_self.clear();
- }
-
- void set_click_handler (
- const any_function<void()>& event_handler_
- )
- {
- auto_mutex M(m);
- event_handler = event_handler_;
- event_handler_self.clear();
- }
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler_)(button&)
- )
- {
- auto_mutex M(m);
- event_handler_self = make_mfp(object,event_handler_);
- event_handler.clear();
- }
-
- void set_sourced_click_handler (
- const any_function<void(button&)>& event_handler_
- )
- {
- auto_mutex M(m);
- event_handler_self = event_handler_;
- event_handler.clear();
- }
-
- bool is_depressed (
- ) const
- {
- auto_mutex M(m);
- return button_action::is_depressed();
- }
-
- template <
- typename T
- >
- void set_button_down_handler (
- T& object,
- void (T::*event_handler)()
- )
- {
- auto_mutex M(m);
- button_down_handler = make_mfp(object,event_handler);
- }
-
- void set_button_down_handler (
- const any_function<void()>& event_handler
- )
- {
- auto_mutex M(m);
- button_down_handler = event_handler;
- }
-
- template <
- typename T
- >
- void set_button_up_handler (
- T& object,
- void (T::*event_handler)(bool mouse_over)
- )
- {
- auto_mutex M(m);
- button_up_handler = make_mfp(object,event_handler);
- }
-
- void set_button_up_handler (
- const any_function<void(bool)>& event_handler
- )
- {
- auto_mutex M(m);
- button_up_handler = event_handler;
- }
-
- template <
- typename T
- >
- void set_button_down_handler (
- T& object,
- void (T::*event_handler)(button&)
- )
- {
- auto_mutex M(m);
- button_down_handler_self = make_mfp(object,event_handler);
- }
-
- void set_sourced_button_down_handler (
- const any_function<void(button&)>& event_handler
- )
- {
- auto_mutex M(m);
- button_down_handler_self = event_handler;
- }
-
- template <
- typename T
- >
- void set_button_up_handler (
- T& object,
- void (T::*event_handler)(bool mouse_over, button&)
- )
- {
- auto_mutex M(m);
- button_up_handler_self = make_mfp(object,event_handler);
- }
-
- void set_sourced_button_up_handler (
- const any_function<void(bool,button&)>& event_handler
- )
- {
- auto_mutex M(m);
- button_up_handler_self = event_handler;
- }
-
- private:
-
- // restricted functions
- button(button&); // copy constructor
- button& operator=(button&); // assignment operator
-
- dlib::ustring name_;
- tooltip btn_tooltip;
-
- any_function<void()> event_handler;
- any_function<void(button&)> event_handler_self;
- any_function<void()> button_down_handler;
- any_function<void(bool)> button_up_handler;
- any_function<void(button&)> button_down_handler_self;
- any_function<void(bool,button&)> button_up_handler_self;
-
- std::unique_ptr<button_style> style;
-
- protected:
-
- void draw (
- const canvas& c
- ) const { style->draw_button(c,rect,enabled,*mfont,lastx,lasty,name_,is_depressed()); }
-
- void on_button_up (
- bool mouse_over
- );
-
- void on_button_down (
- );
-
- void on_mouse_over (
- ){ if (style->redraw_on_mouse_over()) parent.invalidate_rectangle(style->get_invalidation_rect(rect)); }
-
- void on_mouse_not_over (
- ){ if (style->redraw_on_mouse_over()) parent.invalidate_rectangle(style->get_invalidation_rect(rect)); }
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class scroll_bar
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class scroll_bar : public drawable
- {
- /*!
- INITIAL VALUE
- - ori == a value given by the constructor
- - style == a scroll_bar_style_default object
- - pos == 0
- - max_pos == 0
- - js == 10
-
- CONVENTION
- - ori == orientation()
- - b1 == the button that is near the 0 end of the scroll bar
- - b2 == the button that is near the max_pos() end of the scroll bar
-
- - max_pos == max_slider_pos()
- - pos == slider_pos()
- - js == jump_size()
- !*/
-
- public:
- enum bar_orientation
- {
- HORIZONTAL,
- VERTICAL
- };
-
- scroll_bar(
- drawable_window& w,
- bar_orientation orientation_
- );
-
- virtual ~scroll_bar(
- );
-
- bar_orientation orientation (
- ) const;
-
- void set_length (
- unsigned long length
- );
-
- long max_slider_pos (
- ) const;
-
- void set_max_slider_pos (
- long mpos
- );
-
- void set_slider_pos (
- long pos
- );
-
- long slider_pos (
- ) const;
-
- template <
- typename T
- >
- void set_scroll_handler (
- T& object,
- void (T::*eh)()
- ) { auto_mutex M(m); scroll_handler = make_mfp(object,eh); }
-
- void set_scroll_handler (
- const any_function<void()>& eh
- ) { auto_mutex M(m); scroll_handler = eh; }
-
- void set_pos (
- long x,
- long y
- );
-
- void enable (
- )
- {
- auto_mutex M(m);
- if (!hidden)
- show_slider();
- if (max_pos != 0)
- {
- b1.enable();
- b2.enable();
- }
- drawable::enable();
- }
-
- void disable (
- )
- {
- auto_mutex M(m);
- hide_slider();
- b1.disable();
- b2.disable();
- drawable::disable();
- }
-
- void hide (
- )
- {
- auto_mutex M(m);
- hide_slider();
- top_filler.hide();
- bottom_filler.hide();
- b1.hide();
- b2.hide();
- drawable::hide();
- }
-
- void show (
- )
- {
- auto_mutex M(m);
- b1.show();
- b2.show();
- drawable::show();
- top_filler.show();
- if (enabled)
- show_slider();
- }
-
- void set_z_order (
- long order
- )
- {
- auto_mutex M(m);
- slider.set_z_order(order);
- top_filler.set_z_order(order);
- bottom_filler.set_z_order(order);
- b1.set_z_order(order);
- b2.set_z_order(order);
- drawable::set_z_order(order);
- }
-
- void set_jump_size (
- long js
- );
-
- long jump_size (
- ) const;
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- )
- {
- auto_mutex M(m);
- style.reset(new style_type(style_));
-
- if (ori == HORIZONTAL)
- {
- b1.set_style(style_.get_left_button_style());
- b2.set_style(style_.get_right_button_style());
- set_length(rect.width());
- }
- else
- {
- b1.set_style(style_.get_up_button_style());
- b2.set_style(style_.get_down_button_style());
- set_length(rect.height());
- }
-
- }
-
- private:
-
- void hide_slider (
- );
- /*!
- ensures
- - hides the slider and makes any other changes needed so that the
- scroll_bar still looks right.
- !*/
-
- void show_slider (
- );
- /*!
- ensures
- - shows the slider and makes any other changes needed so that the
- scroll_bar still looks right.
- !*/
-
-
- void on_slider_drag (
- );
- /*!
- requires
- - is called whenever the user drags the slider
- !*/
-
- void draw (
- const canvas& c
- ) const;
-
- void b1_down (
- );
-
- void b1_up (
- bool mouse_over
- );
-
- void b2_down (
- );
-
- void b2_up (
- bool mouse_over
- );
-
- void top_filler_down (
- );
-
- void top_filler_up (
- bool mouse_over
- );
-
- void bottom_filler_down (
- );
-
- void bottom_filler_up (
- bool mouse_over
- );
-
- void on_user_event (
- int i
- );
-
- void delayed_set_slider_pos (
- unsigned long dpos
- );
-
- void b1_down_t (
- );
-
- void b2_down_t (
- );
-
- void top_filler_down_t (
- );
-
- void bottom_filler_down_t (
- );
-
- friend class filler;
- class filler : public button_action
- {
- friend class scroll_bar;
- public:
- filler (
- drawable_window& w,
- scroll_bar& object,
- void (scroll_bar::*down)(),
- void (scroll_bar::*up)(bool)
- ):
- button_action(w),
- my_scroll_bar(object)
- {
- bup = make_mfp(object,up);
- bdown = make_mfp(object,down);
-
- enable_events();
- }
-
- ~filler (
- )
- {
- disable_events();
- }
-
- void set_size (
- unsigned long width,
- unsigned long height
- )
- {
- rectangle old(rect);
- const unsigned long x = rect.left();
- const unsigned long y = rect.top();
- rect.set_right(x+width-1);
- rect.set_bottom(y+height-1);
-
- parent.invalidate_rectangle(rect+old);
- }
-
- private:
-
- void draw (
- const canvas& c
- ) const
- {
- my_scroll_bar.style->draw_scroll_bar_background(c,rect,enabled,lastx,lasty,is_depressed());
- }
-
- void on_button_down (
- ) { bdown(); }
-
- void on_button_up (
- bool mouse_over
- ) { bup(mouse_over); }
-
- scroll_bar& my_scroll_bar;
- any_function<void()> bdown;
- any_function<void(bool)> bup;
- };
-
- friend class slider_class;
- class slider_class : public draggable
- {
- friend class scroll_bar;
- public:
- slider_class (
- drawable_window& w,
- scroll_bar& object,
- void (scroll_bar::*handler)()
- ) :
- draggable(w, MOUSE_MOVE),
- mouse_in_widget(false),
- my_scroll_bar(object)
- {
- callback = make_mfp(object,handler);
- enable_events();
- }
-
- ~slider_class (
- )
- {
- disable_events();
- }
-
- void set_size (
- unsigned long width,
- unsigned long height
- )
- {
- rectangle old(rect);
- const unsigned long x = rect.left();
- const unsigned long y = rect.top();
- rect.set_right(x+width-1);
- rect.set_bottom(y+height-1);
-
- parent.invalidate_rectangle(rect+old);
- }
-
- private:
- virtual void on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- draggable::on_mouse_move(state,x,y);
- if (!hidden && my_scroll_bar.style->redraw_on_mouse_over_slider())
- {
- if (rect.contains(x,y) && !mouse_in_widget)
- {
- mouse_in_widget = true;
- parent.invalidate_rectangle(rect);
- }
- else if (rect.contains(x,y) == false && mouse_in_widget)
- {
- mouse_in_widget = false;
- parent.invalidate_rectangle(rect);
- }
- }
- }
-
- void on_mouse_leave (
- )
- {
- if (mouse_in_widget && my_scroll_bar.style->redraw_on_mouse_over_slider())
- {
- mouse_in_widget = false;
- parent.invalidate_rectangle(rect);
- }
- }
-
- void on_drag_stop (
- )
- {
- if (my_scroll_bar.style->redraw_on_mouse_over_slider())
- parent.invalidate_rectangle(rect);
- }
-
- void on_drag (
- )
- {
- callback();
- }
-
- void draw (
- const canvas& c
- ) const
- {
- my_scroll_bar.style->draw_scroll_bar_slider(c,rect,enabled,lastx,lasty, is_being_dragged());
- }
-
- bool mouse_in_widget;
- scroll_bar& my_scroll_bar;
- any_function<void()> callback;
- };
-
-
- void adjust_fillers (
- );
- /*!
- ensures
- - top_filler and bottom_filler appear in their correct positions
- relative to the current positions of the slider and the b1 and
- b2 buttons
- !*/
-
- unsigned long get_slider_size (
- ) const;
- /*!
- ensures
- - returns the length in pixels the slider should have based on the current
- state of this scroll bar
- !*/
-
-
- button b1, b2;
- slider_class slider;
- bar_orientation ori;
- filler top_filler, bottom_filler;
- any_function<void()> scroll_handler;
-
- long pos;
- long max_pos;
- long js;
-
- timer<scroll_bar> b1_timer;
- timer<scroll_bar> b2_timer;
- timer<scroll_bar> top_filler_timer;
- timer<scroll_bar> bottom_filler_timer;
- long delayed_pos;
- std::unique_ptr<scroll_bar_style> style;
-
- // restricted functions
- scroll_bar(scroll_bar&); // copy constructor
- scroll_bar& operator=(scroll_bar&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class popup_menu
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class menu_item
- {
- public:
- virtual ~menu_item() {}
-
- virtual rectangle get_left_size (
- ) const { return rectangle(); }
- virtual rectangle get_middle_size (
- ) const = 0;
- virtual rectangle get_right_size (
- ) const { return rectangle(); }
-
- virtual unichar get_hot_key (
- ) const { return 0; }
-
- virtual void draw_background (
- const canvas& ,
- const rectangle& ,
- const bool ,
- const bool
- ) const {}
-
- virtual void draw_left (
- const canvas& ,
- const rectangle& ,
- const bool ,
- const bool
- ) const {}
-
- virtual void draw_middle (
- const canvas& ,
- const rectangle& ,
- const bool ,
- const bool
- ) const = 0;
-
- virtual void draw_right (
- const canvas& ,
- const rectangle& ,
- const bool ,
- const bool
- ) const {}
-
- virtual void on_click (
- ) const {}
-
- virtual bool has_click_event (
- ) const { return false; }
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class menu_item_submenu : public menu_item
- {
- void initialize (
- unichar hk
- )
- {
- const dlib::ustring &str = text;
- if (hk != 0)
- {
- std::string::size_type pos = str.find_first_of(hk);
- if (pos != std::string::npos)
- {
- // now compute the location of the underline bar
- rectangle r1 = f->compute_cursor_rect( rectangle(100000,100000), str, pos);
- rectangle r2 = f->compute_cursor_rect( rectangle(100000,100000), str, pos+1);
-
- underline_p1.x() = r1.left()+1;
- underline_p2.x() = r2.left()-1;
- underline_p1.y() = r1.bottom()-f->height()+f->ascender()+2;
- underline_p2.y() = r2.bottom()-f->height()+f->ascender()+2;
- }
- }
- }
- public:
- menu_item_submenu (
- const std::string& str,
- unichar hk = 0
- ) :
- text(convert_wstring_to_utf32(convert_mbstring_to_wstring(str))),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(hk);
- }
-
- menu_item_submenu (
- const std::wstring& str,
- unichar hk = 0
- ) :
- text(convert_wstring_to_utf32(str)),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(hk);
- }
-
- menu_item_submenu (
- const dlib::ustring& str,
- unichar hk = 0
- ) :
- text(str),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(hk);
- }
-
- virtual unichar get_hot_key (
- ) const { return hotkey; }
-
- virtual rectangle get_middle_size (
- ) const
- {
- unsigned long width, height;
- f->compute_size(text,width,height);
- return rectangle(width+30,height);
- }
-
- virtual rectangle get_right_size (
- ) const
- {
- return rectangle(15, 5);
- }
-
- virtual void draw_background (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool is_selected
- ) const
- {
- if (c.intersect(rect).is_empty())
- return;
-
- if (enabled && is_selected)
- {
- fill_rect_with_vertical_gradient(c, rect,rgb_alpha_pixel(0,200,0,100), rgb_alpha_pixel(0,0,0,100));
- draw_rectangle(c, rect,rgb_alpha_pixel(0,0,0,100));
- }
- }
-
- virtual void draw_right (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool
- ) const
- {
- if (c.intersect(rect).is_empty())
- return;
-
- unsigned char color = 0;
-
- if (enabled == false)
- color = 128;
-
- long x, y;
- x = rect.right() - 7;
- y = rect.top() + rect.height()/2;
-
- for ( unsigned long i = 0; i < 5; ++i)
- draw_line (c, point(x - i, y + i), point(x - i, y - i), color);
- }
-
- virtual void draw_middle (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool
- ) const
- {
- if (c.intersect(rect).is_empty())
- return;
-
- if (enabled)
- {
- f->draw_string(c,rect,text);
- }
- else
- {
- f->draw_string(c,rect,text,128);
- }
-
- if (underline_p1 != underline_p2)
- {
- point base(rect.left(),rect.top());
- draw_line(c, base+underline_p1, base+underline_p2);
- }
- }
-
- private:
- dlib::ustring text;
- const std::shared_ptr<font> f;
- any_function<void()> action;
- unichar hotkey;
- point underline_p1;
- point underline_p2;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class menu_item_text : public menu_item
- {
- void initialize (
- const any_function<void()>& event_handler_,
- unichar hk
- )
- {
- dlib::ustring &str = text;
- action = event_handler_;
-
- if (hk != 0)
- {
- std::string::size_type pos = str.find_first_of(hk);
- if (pos != std::string::npos)
- {
- // now compute the location of the underline bar
- rectangle r1 = f->compute_cursor_rect( rectangle(100000,100000), str, pos);
- rectangle r2 = f->compute_cursor_rect( rectangle(100000,100000), str, pos+1);
-
- underline_p1.x() = r1.left()+1;
- underline_p2.x() = r2.left()-1;
- underline_p1.y() = r1.bottom()-f->height()+f->ascender()+2;
- underline_p2.y() = r2.bottom()-f->height()+f->ascender()+2;
- }
- }
- }
-
- public:
- template <typename T>
- menu_item_text (
- const std::string& str,
- T& object,
- void (T::*event_handler_)(),
- unichar hk = 0
- ) :
- text(convert_wstring_to_utf32(convert_mbstring_to_wstring(str))),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(make_mfp(object, event_handler_), hk);
- }
-
- menu_item_text (
- const std::string& str,
- const any_function<void()>& event_handler_,
- unichar hk = 0
- ) :
- text(convert_wstring_to_utf32(convert_mbstring_to_wstring(str))),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(event_handler_, hk);
- }
-
- template <typename T>
- menu_item_text (
- const std::wstring& str,
- T& object,
- void (T::*event_handler_)(),
- unichar hk = 0
- ) :
- text(convert_wstring_to_utf32(str)),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(make_mfp(object, event_handler_), hk);
- }
-
- menu_item_text (
- const std::wstring& str,
- const any_function<void()>& event_handler_,
- unichar hk = 0
- ) :
- text(convert_wstring_to_utf32(str)),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(event_handler_, hk);
- }
-
- template <typename T>
- menu_item_text (
- const dlib::ustring& str,
- T& object,
- void (T::*event_handler_)(),
- unichar hk = 0
- ) :
- text(str),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(make_mfp(object, event_handler_), hk);
- }
-
- menu_item_text (
- const dlib::ustring& str,
- const any_function<void()>& event_handler_,
- unichar hk = 0
- ) :
- text(str),
- f(default_font::get_font()),
- hotkey(hk)
- {
- initialize(event_handler_, hk);
- }
-
- virtual unichar get_hot_key (
- ) const { return hotkey; }
-
- virtual rectangle get_middle_size (
- ) const
- {
- unsigned long width, height;
- f->compute_size(text,width,height);
- return rectangle(width,height);
- }
-
- virtual void draw_background (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool is_selected
- ) const
- {
- if (c.intersect(rect).is_empty())
- return;
-
- if (enabled && is_selected)
- {
- fill_rect_with_vertical_gradient(c, rect,rgb_alpha_pixel(0,200,0,100), rgb_alpha_pixel(0,0,0,100));
- draw_rectangle(c, rect,rgb_alpha_pixel(0,0,0,100));
- }
- }
-
- virtual void draw_middle (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool
- ) const
- {
- if (c.intersect(rect).is_empty())
- return;
-
- unsigned char color = 0;
-
- if (enabled == false)
- color = 128;
-
- f->draw_string(c,rect,text,color);
-
- if (underline_p1 != underline_p2)
- {
- point base(rect.left(),rect.top());
- draw_line(c, base+underline_p1, base+underline_p2, color);
- }
- }
-
- virtual void on_click (
- ) const
- {
- action();
- }
-
- virtual bool has_click_event (
- ) const { return true; }
-
- private:
- dlib::ustring text;
- const std::shared_ptr<font> f;
- any_function<void()> action;
- unichar hotkey;
- point underline_p1;
- point underline_p2;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class menu_item_separator : public menu_item
- {
- public:
- virtual rectangle get_middle_size (
- ) const
- {
- return rectangle(10,4);
- }
-
- virtual void draw_background (
- const canvas& c,
- const rectangle& rect,
- const bool ,
- const bool
- ) const
- {
- if (c.intersect(rect).is_empty())
- return;
-
- point p1(rect.left(),rect.top()+rect.height()/2-1);
- point p2(rect.right(),rect.top()+rect.height()/2-1);
-
- point p3(rect.left(),rect.top()+rect.height()/2);
- point p4(rect.right(),rect.top()+rect.height()/2);
- draw_line(c, p1,p2,128);
- draw_line(c, p3,p4,255);
- }
-
- virtual void draw_middle (
- const canvas& ,
- const rectangle& ,
- const bool ,
- const bool
- ) const
- {
- }
- };
-
-// ----------------------------------------------------------------------------------------
-
- class popup_menu : public base_window
- {
- /*!
- INITIAL VALUE
- - pad == 2
- - item_pad == 3
- - cur_rect == rectangle(pad,pad,pad-1,pad-1)
- - left_width == 0
- - middle_width == 0
- - selected_item == 0
- - submenu_open == false
- - items.size() == 0
- - item_enabled.size() == 0
- - left_rects.size() == 0
- - middle_rects.size() == 0
- - right_rects.size() == 0
- - line_rects.size() == 0
- - submenus.size() == 0
- - hide_handlers.size() == 0
-
- CONVENTION
- - pad = 2
- - item_pad = 3
- - all of the following arrays have the same size:
- - items.size()
- - item_enabled.size()
- - left_rects.size()
- - middle_rects.size()
- - right_rects.size()
- - line_rects.size()
- - submenus.size()
-
- - win_rect == a rectangle that is the exact size of this window and with
- its upper left corner at (0,0)
- - cur_rect == the rect inside which all the menu items are drawn
-
- - if (a menu_item is supposed to be selected) then
- - selected_item == the index in menus of the menu_item
- - else
- - selected_item == submenus.size()
-
- - if (there is a selected submenu and it is currently open) then
- - submenu_open == true
- - else
- - submenu_open == false
-
- - for all valid i:
- - items[i] == a pointer to the ith menu_item
- - item_enabled[i] == true if the ith menu_item is enabled, false otherwise
- - left_rects[i] == the left rectangle for the ith menu item
- - middle_rects[i] == the middle rectangle for the ith menu item
- - right_rects[i] == the right rectangle for the ith menu item
- - line_rects[i] == the rectangle for the entire line on which the ith menu
- item appears.
- - if (submenus[i] != 0) then
- - the ith menu item has a submenu and it is pointed to by submenus[i]
-
- - hide_handlers == an array of all the on_hide events registered for
- this popup_menu
- !*/
-
- public:
-
- popup_menu (
- );
-
- template <
- typename menu_item_type
- >
- unsigned long add_menu_item (
- const menu_item_type& new_item
- )
- {
- auto_mutex M(wm);
- bool t = true;
- std::unique_ptr<menu_item> item(new menu_item_type(new_item));
- items.push_back(item);
- item_enabled.push_back(t);
-
- // figure out how big the window should be now and what not
- rectangle left = new_item.get_left_size();
- rectangle middle = new_item.get_middle_size();
- rectangle right = new_item.get_right_size();
-
- bool recalc_rect_positions = false;
- const rectangle all = left+middle+right;
-
-
- // make sure left_width contains the max of all the left rectangles
- if (left.width() > left_width)
- {
- left_width = left.width();
- recalc_rect_positions = true;
- }
- // make sure middle_width contains the max of all the middle rectangles
- if (middle.width() > middle_width)
- {
- middle_width = middle.width();
- recalc_rect_positions = true;
- }
-
- // make the current rectangle wider if necessary
- if (cur_rect.width() < left_width + middle_width + right.width() + 2*item_pad)
- {
- cur_rect = resize_rect_width(cur_rect, left_width + middle_width + right.width() + 2*item_pad);
- recalc_rect_positions = true;
- }
-
- const long y = cur_rect.bottom()+1 + item_pad;
- const long x = cur_rect.left() + item_pad;
-
- // make the current rectangle taller to account for this new menu item
- cur_rect.set_bottom(cur_rect.bottom()+all.height() + 2*item_pad);
-
- // adjust all the saved rectangles since the width of the window changed
- // or left_width changed
- if (recalc_rect_positions)
- {
- long y = cur_rect.top() + item_pad;
- for (unsigned long i = 0; i < left_rects.size(); ++i)
- {
- middle_rects[i] = move_rect(middle_rects[i], x+left_width, y);
- right_rects[i] = move_rect(right_rects[i], x+cur_rect.width()-right_rects[i].width()-item_pad, y);
- line_rects[i] = resize_rect_width(line_rects[i], cur_rect.width());
-
- y += line_rects[i].height();
- }
- }
-
- // save the rectangles for later use. Also position them at the
- // right spots
- left = move_rect(left,x,y);
- middle = move_rect(middle,x+left_width,y);
- right = move_rect(right,x+cur_rect.width()-right.width()-item_pad,y);
- rectangle line(move_rect(rectangle(cur_rect.width(),all.height()+2*item_pad), x-item_pad, y-item_pad));
-
- // make sure the left, middle, and right rectangles are centered in the
- // line.
- if (left.height() < all.height())
- left = translate_rect(left,0, (all.height()-left.height())/2);
- if (middle.height() < all.height())
- middle = translate_rect(middle,0, (all.height()-middle.height())/2);
- if (right.height() < all.height())
- right = translate_rect(right,0, (all.height()-right.height())/2);
-
- left_rects.push_back(left);
- middle_rects.push_back(middle);
- right_rects.push_back(right);
- line_rects.push_back(line);
-
- popup_menu* junk = 0;
- submenus.push_back(junk);
-
- win_rect.set_right(cur_rect.right()+pad);
- win_rect.set_bottom(cur_rect.bottom()+pad);
- set_size(win_rect.width(),win_rect.height());
-
- // make it so that nothing is selected
- selected_item = submenus.size();
-
- return items.size()-1;
- }
-
- template <
- typename menu_item_type
- >
- unsigned long add_submenu (
- const menu_item_type& new_item,
- popup_menu& submenu
- )
- {
- auto_mutex M(wm);
-
- submenus[add_menu_item(new_item)] = &submenu;
-
- submenu.set_on_hide_handler(*this,&popup_menu::on_submenu_hide);
-
- return items.size()-1;
- }
-
- void enable_menu_item (
- unsigned long idx
- );
-
- void disable_menu_item (
- unsigned long idx
- );
-
- size_t size (
- ) const;
-
- void clear (
- );
-
- void show (
- );
-
- void hide (
- );
-
- template <typename T>
- void set_on_hide_handler (
- T& object,
- void (T::*event_handler)()
- )
- {
- auto_mutex M(wm);
-
- member_function_pointer<> temp;
- temp.set(object,event_handler);
-
- // if this handler isn't already registered then add it
- bool found_handler = false;
- for (unsigned long i = 0; i < hide_handlers.size(); ++i)
- {
- if (hide_handlers[i] == temp)
- {
- found_handler = true;
- break;
- }
- }
-
- if (found_handler == false)
- {
- hide_handlers.push_back(temp);
- }
- }
-
- void select_first_item (
- );
-
- bool forwarded_on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- private:
-
- void on_submenu_hide (
- );
-
- void on_window_resized(
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long,
- long x,
- long y
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void close_submenu (
- );
-
- bool display_selected_submenu (
- );
- /*!
- ensures
- - if (submenus[selected_item] isn't null) then
- - displays the selected submenu
- - returns true
- - else
- - returns false
- !*/
-
- void on_mouse_leave (
- );
-
- void paint (
- const canvas& c
- );
-
- const long pad;
- const long item_pad;
- rectangle cur_rect;
- rectangle win_rect;
- unsigned long left_width;
- unsigned long middle_width;
- array<std::unique_ptr<menu_item> > items;
- array<bool> item_enabled;
- array<rectangle> left_rects;
- array<rectangle> middle_rects;
- array<rectangle> right_rects;
- array<rectangle> line_rects;
- array<popup_menu*> submenus;
- unsigned long selected_item;
- bool submenu_open;
- array<member_function_pointer<> > hide_handlers;
-
- // restricted functions
- popup_menu(popup_menu&); // copy constructor
- popup_menu& operator=(popup_menu&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class zoomable_region : public drawable
- {
- /*!
- INITIAL VALUE
- - min_scale == 0.15
- - max_scale == 1.0
- - zoom_increment_ == 0.02
- - scale == 1.0
- - mouse_drag_screen == false
-
-
- CONVENTION
- - zoom_increment() == zoom_increment_
- - min_zoom_scale() == min_scale
- - max_zoom_scale() == max_scale
- - zoom_scale() == scale
- - if (the user is currently dragging the graph around via the mouse) then
- - mouse_drag_screen == true
- - else
- - mouse_drag_screen == false
-
- - max_graph_point() == lr_point
- - display_rect() == display_rect_
- - gui_to_graph_space(point(display_rect.left(),display_rect.top())) == gr_orig
- !*/
-
- public:
-
- zoomable_region (
- drawable_window& w,
- unsigned long events = 0
- );
-
- virtual ~zoomable_region (
- )= 0;
-
- virtual void set_pos (
- long x,
- long y
- );
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- )
- {
- auto_mutex M(m);
- style.reset(new style_type(style_));
- hsb.set_style(style_.get_horizontal_scroll_bar_style());
- vsb.set_style(style_.get_vertical_scroll_bar_style());
-
- // do this just so that everything gets redrawn right
- set_size(rect.width(), rect.height());
- }
-
- void set_zoom_increment (
- double zi
- );
-
- double zoom_increment (
- ) const;
-
- void set_max_zoom_scale (
- double ms
- );
-
- void set_min_zoom_scale (
- double ms
- );
-
- double min_zoom_scale (
- ) const;
-
- double max_zoom_scale (
- ) const;
-
- virtual void set_size (
- unsigned long width,
- unsigned long height
- );
-
- void show (
- );
-
- void hide (
- );
-
- void enable (
- );
-
- void disable (
- );
-
- void set_z_order (
- long order
- );
-
- protected:
-
- virtual void on_view_changed () {}
-
- point graph_to_gui_space (
- const vector<double,2>& p
- ) const;
-
- vector<double,2> gui_to_graph_space (
- const point& p
- ) const;
-
- point max_graph_point (
- ) const;
-
- rectangle display_rect (
- ) const;
-
- double zoom_scale (
- ) const;
-
- void set_zoom_scale (
- double new_scale
- );
-
- void center_display_at_graph_point (
- const vector<double,2>& p
- );
-
- // ----------- event handlers ---------------
-
- void on_wheel_down (
- unsigned long state
- );
-
- void on_wheel_up (
- unsigned long state
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void draw (
- const canvas& c
- ) const;
-
- private:
-
- void on_h_scroll (
- );
-
- void on_v_scroll (
- );
-
- void redraw_graph (
- );
-
- void adjust_origin (
- const point& gui_p,
- const vector<double,2>& graph_p
- );
- /*!
- ensures
- - adjusts gr_orig so that we are as close to the following as possible:
- - graph_to_gui_space(graph_p) == gui_p
- - gui_to_graph_space(gui_p) == graph_p
- !*/
-
-
- vector<double,2> gr_orig; // point in graph space such that it's gui space point is the upper left of display_rect_
- vector<double,2> lr_point; // point in graph space such that it is at the lower right corner of the screen at max zoom
-
- mutable std::ostringstream sout;
-
- double scale; // 0 < scale <= 1
- double min_scale;
- double max_scale;
- double zoom_increment_;
- rectangle display_rect_;
-
- bool mouse_drag_screen; // true if the user is dragging the white background area
- vector<double,2> drag_screen_point; // the starting point the mouse was at in graph space for the background area drag
-
- scroll_bar vsb;
- scroll_bar hsb;
-
- std::unique_ptr<scrollable_region_style> style;
-
- // restricted functions
- zoomable_region(zoomable_region&); // copy constructor
- zoomable_region& operator=(zoomable_region&); // assignment operator
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class scrollable_region : public drawable
- {
- /*!
- INITIAL VALUE
- - hscroll_bar_inc == 1
- - vscroll_bar_inc == 1
- - h_wheel_scroll_bar_inc == 1
- - v_wheel_scroll_bar_inc == 1
- - mouse_drag_enabled_ == false
- - user_is_dragging_mouse == false
-
- CONVENTION
- - mouse_drag_enabled() == mouse_drag_enabled_
- - horizontal_scroll_increment() == hscroll_bar_inc
- - vertical_scroll_increment() == vscroll_bar_inc
- - horizontal_mouse_wheel_scroll_increment() == h_wheel_scroll_bar_inc
- - vertical_mouse_wheel_scroll_increment() == v_wheel_scroll_bar_inc
- - vertical_scroll_pos() == vsb.slider_pos()
- - horizontal_scroll_pos() == hsb.slider_pos()
- - total_rect() == total_rect_
- - display_rect() == display_rect_
-
- - if (the user is currently dragging the total_rect around with a mouse drag) then
- - user_is_dragging_mouse == true
- - drag_origin == the point the mouse was at, with respect to total_rect,
- when the dragging started
- - else
- - user_is_dragging_mouse == false
- !*/
-
- public:
-
- scrollable_region (
- drawable_window& w,
- unsigned long events = 0
- );
-
- virtual ~scrollable_region (
- ) = 0;
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- )
- {
- auto_mutex M(m);
- style.reset(new style_type(style_));
- hsb.set_style(style_.get_horizontal_scroll_bar_style());
- vsb.set_style(style_.get_vertical_scroll_bar_style());
-
- // do this just so that everything gets redrawn right
- set_size(rect.width(), rect.height());
- }
-
- void show (
- );
-
- void hide (
- );
-
- void enable (
- );
-
- void disable (
- );
-
- void set_z_order (
- long order
- );
-
- virtual void set_size (
- unsigned long width,
- unsigned long height
- );
-
- unsigned long horizontal_mouse_wheel_scroll_increment (
- ) const;
-
- unsigned long vertical_mouse_wheel_scroll_increment (
- ) const;
-
- void set_horizontal_mouse_wheel_scroll_increment (
- unsigned long inc
- );
-
- void set_vertical_mouse_wheel_scroll_increment (
- unsigned long inc
- );
-
- unsigned long horizontal_scroll_increment (
- ) const;
-
- unsigned long vertical_scroll_increment (
- ) const;
-
- void set_horizontal_scroll_increment (
- unsigned long inc
- );
-
- void set_vertical_scroll_increment (
- unsigned long inc
- );
-
- long horizontal_scroll_pos (
- ) const;
-
- long vertical_scroll_pos (
- ) const;
-
- void set_horizontal_scroll_pos (
- long pos
- );
-
- void set_vertical_scroll_pos (
- long pos
- );
-
- virtual void set_pos (
- long x,
- long y
- );
-
- bool mouse_drag_enabled (
- ) const;
-
- void enable_mouse_drag (
- );
-
- void disable_mouse_drag (
- );
-
- protected:
-
- virtual void on_view_changed () {}
-
- const rectangle& display_rect (
- ) const;
-
- void set_total_rect_size (
- unsigned long width,
- unsigned long height
- );
-
- const rectangle& total_rect (
- ) const;
-
- void scroll_to_rect (
- const rectangle& r_
- );
-
- void on_wheel_down (
- unsigned long state
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- );
-
- void on_wheel_up (
- unsigned long state
- );
-
- void draw (
- const canvas& c
- ) const;
-
- private:
-
- bool need_h_scroll (
- ) const;
-
- bool need_v_scroll (
- ) const;
-
- void on_h_scroll (
- );
-
- void on_v_scroll (
- );
-
- rectangle total_rect_;
- rectangle display_rect_;
- scroll_bar hsb;
- scroll_bar vsb;
- unsigned long hscroll_bar_inc;
- unsigned long vscroll_bar_inc;
- unsigned long h_wheel_scroll_bar_inc;
- unsigned long v_wheel_scroll_bar_inc;
- bool mouse_drag_enabled_;
- bool user_is_dragging_mouse;
- point drag_origin;
- std::unique_ptr<scrollable_region_style> style;
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class popup_menu_region
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class popup_menu_region : public drawable
- {
- /*!
- CONVENTION
- popup_menu_visible() == popup_menu_shown
- !*/
-
- public:
-
- popup_menu_region(
- drawable_window& w
- );
-
- virtual ~popup_menu_region(
- );
-
- void set_size (
- unsigned long width,
- unsigned long height
- );
-
- void set_rect (
- const rectangle& new_rect
- );
-
- popup_menu& menu (
- );
-
- void hide (
- );
-
- void disable (
- );
-
- bool popup_menu_visible (
- ) const { auto_mutex M(m); return popup_menu_shown; }
-
- protected:
-
- void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- void on_focus_lost (
- );
-
- void on_focus_gained (
- );
-
- void on_window_moved(
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void on_menu_becomes_hidden (
- );
-
- void draw (
- const canvas&
- ) const;
-
- private:
-
- popup_menu menu_;
- bool popup_menu_shown;
-
- // restricted functions
- popup_menu_region(popup_menu_region&); // copy constructor
- popup_menu_region& operator=(popup_menu_region&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "base_widgets.cpp"
-#endif
-
-#endif // DLIB_BASE_WIDGETs_
-
diff --git a/ml/dlib/dlib/gui_widgets/base_widgets_abstract.h b/ml/dlib/dlib/gui_widgets/base_widgets_abstract.h
deleted file mode 100644
index 3dcee0d5a..000000000
--- a/ml/dlib/dlib/gui_widgets/base_widgets_abstract.h
+++ /dev/null
@@ -1,2290 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_BASE_WIDGETs_ABSTRACT_
-#ifdef DLIB_BASE_WIDGETs_ABSTRACT_
-
-#include "fonts_abstract.h"
-#include "drawable_abstract.h"
-
-#include "../gui_core.h"
-#include <string>
-
-namespace dlib
-{
-
- /*!
- GENERAL REMARKS
- This file contains objects that are useful for creating complex drawable
- widgets.
-
- THREAD SAFETY
- All objects and functions defined in this file are thread safe. You may
- call them from any thread without serializing access to them.
-
- EVENT HANDLERS
- If you derive from any of the drawable objects and redefine any of the on_*()
- event handlers then you should ensure that your version calls the same event
- handler in the base object so that the base class part of your object will also
- be able to process the event.
-
- Also note that all event handlers, including the user registered callback
- functions, are executed in the event handling thread. Additionally,
- the drawable::m mutex will always be locked while these event handlers
- are running. Also, don't rely on get_thread_id() always returning the
- same ID from inside event handlers.
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class draggable
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class draggable : public drawable
- {
- /*!
- INITIAL VALUE
- draggable_area() == an initial value for its type
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a drawable object that is draggable by the mouse.
- You use it by inheriting from it and defining the draw() method and any
- of the on_*() event handlers you need.
-
- This object is draggable by the user when is_enabled() == true and
- not draggable otherwise.
- !*/
-
- public:
-
- draggable(
- drawable_window& w,
- unsigned long events = 0
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- - This object will not receive any events or draw() requests until
- enable_events() is called
- - the events flags are passed on to the drawable object's
- constructor.
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~draggable(
- ) = 0;
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- rectangle draggable_area (
- ) const;
- /*!
- ensures
- - returns the area that this draggable can be dragged around in.
- !*/
-
- void set_draggable_area (
- const rectangle& area
- );
- /*!
- ensures
- - #draggable_area() == area
- !*/
-
- protected:
-
- bool is_being_dragged (
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - if (this widget is currently being dragged by the user) then
- - returns true
- - else
- - returns false
- !*/
-
- // does nothing by default
- virtual void on_drag (
- ){}
- /*!
- requires
- - enable_events() has been called
- - is_enabled() == true
- - is_hidden() == false
- - mutex drawable::m is locked
- - is called when the user drags this object
- - get_rect() == the rectangle that defines the new position
- of this object.
- - is_being_dragged() == true
- ensures
- - does not change the state of mutex drawable::m.
- !*/
-
- // does nothing by default
- virtual void on_drag_stop (
- ){}
- /*!
- requires
- - enable_events() has been called
- - mutex drawable::m is locked
- - is called when the user stops dragging this object
- - is_being_dragged() == false
- ensures
- - does not change the state of mutex drawable::m.
- !*/
-
- private:
-
- // restricted functions
- draggable(draggable&); // copy constructor
- draggable& operator=(draggable&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class mouse_over_event
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class mouse_over_event : public drawable
- {
- /*!
- INITIAL VALUE
- is_mouse_over() == false
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a drawable object with the addition of two events
- that will alert you when the mouse enters or leaves your drawable object.
-
- You use it by inheriting from it and defining the draw() method and any
- of the on_*() event handlers you need.
- !*/
-
- public:
-
- mouse_over_event(
- drawable_window& w,
- unsigned long events = 0
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- - #*this will not receive any events or draw() requests until
- enable_events() is called
- - the events flags are passed on to the drawable object's
- constructor.
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~mouse_over_event(
- ) = 0;
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- protected:
-
- bool is_mouse_over (
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - if (the mouse is currently over this widget) then
- - returns true
- - else
- - returns false
- !*/
-
- // does nothing by default
- virtual void on_mouse_over (
- ){}
- /*!
- requires
- - enable_events() has been called
- - mutex drawable::m is locked
- - is_enabled() == true
- - is_hidden() == false
- - is called whenever this object transitions from the state where
- is_mouse_over() == false to is_mouse_over() == true
- ensures
- - does not change the state of mutex drawable::m.
- !*/
-
- // does nothing by default
- virtual void on_mouse_not_over (
- ){}
- /*!
- requires
- - enable_events() has been called
- - mutex drawable::m is locked
- - is called whenever this object transitions from the state where
- is_mouse_over() == true to is_mouse_over() == false
- ensures
- - does not change the state of mutex drawable::m.
- !*/
-
- private:
-
- // restricted functions
- mouse_over_event(mouse_over_event&); // copy constructor
- mouse_over_event& operator=(mouse_over_event&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class button_action
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class button_action : public mouse_over_event
- {
- /*!
- INITIAL VALUE
- is_depressed() == false
-
- WHAT THIS OBJECT REPRESENTS
- This object represents the clicking action of a push button. It provides
- simple callbacks that can be used to make various kinds of button
- widgets.
-
- You use it by inheriting from it and defining the draw() method and any
- of the on_*() event handlers you need.
- !*/
-
- public:
-
- button_action(
- drawable_window& w,
- unsigned long events = 0
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- - #*this will not receive any events or draw() requests until
- enable_events() is called
- - the events flags are passed on to the drawable object's
- constructor.
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~button_action(
- ) = 0;
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- protected:
-
- bool is_depressed (
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - if (this button is currently in a depressed state) then
- - the user has left clicked on this drawable and is still
- holding the left mouse button down over it.
- - returns true
- - else
- - returns false
- !*/
-
- // does nothing by default
- virtual void on_button_down (
- ){}
- /*!
- requires
- - enable_events() has been called
- - mutex drawable::m is locked
- - is_enabled() == true
- - is_hidden() == false
- - the area in parent_window() defined by get_rect() has been invalidated.
- (This means you don't have to call invalidate_rectangle())
- - is called whenever this object transitions from the state where
- is_depressed() == false to is_depressed() == true
- ensures
- - does not change the state of mutex drawable::m.
- !*/
-
- // does nothing by default
- virtual void on_button_up (
- bool mouse_over
- ){}
- /*!
- requires
- - enable_events() has been called
- - mutex drawable::m is locked
- - the area in parent_window() defined by get_rect() has been invalidated.
- (This means you don't have to call invalidate_rectangle())
- - is called whenever this object transitions from the state where
- is_depressed() == true to is_depressed() == false
- - if (the mouse was over this button when this event occurred) then
- - mouse_over == true
- - else
- - mouse_over == false
- ensures
- - does not change the state of mutex drawable::m.
- !*/
-
- private:
-
- // restricted functions
- button_action(button_action&); // copy constructor
- button_action& operator=(button_action&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class button
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class button : public button_action
- {
- /*!
- INITIAL VALUE
- name() == ""
- tooltip_text() == "" (i.e. there is no tooltip by default)
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple button.
-
- When this object is disabled it means it will not respond to user clicks.
- !*/
-
- public:
-
- button(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~button(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_size (
- unsigned long width_,
- unsigned long height_
- );
- /*!
- ensures
- - if (width and height are big enough to contain the name of this button) then
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this button stays the
- same but its width and height are modified
- !*/
-
- void set_name (const std::wstring& name);
- void set_name (const dlib::ustring& name);
- void set_name (
- const std::string& name
- );
- /*!
- ensures
- - #name() == name
- - this button has been resized such that it is big enough to contain
- the new name.
- throws
- - std::bad_alloc
- !*/
-
- const std::wstring wname () const;
- const dlib::string uname () const;
- const std::string name (
- ) const;
- /*!
- ensures
- - returns the name of this button
- throws
- - std::bad_alloc
- !*/
-
- void set_tooltip_text (const std::wstring& text);
- void set_tooltip_text (const dlib::ustring& text);
- void set_tooltip_text (
- const std::string& text
- );
- /*!
- ensures
- - #tooltip_text() == text
- - enables the tooltip for this button
- !*/
-
- const dlib::ustring tooltip_utext () const;
- const std::wstring tooltip_wtext () const;
- const std::string tooltip_text (
- ) const;
- /*!
- ensures
- - returns the text that is displayed in the tooltip for this button
- !*/
-
- bool is_depressed (
- ) const;
- /*!
- ensures
- - if (this button is currently in a depressed state) then
- - the user has left clicked on this widget and is still
- holding the left mouse button down over it.
- - returns true
- - else
- - returns false
- !*/
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style
- );
- /*!
- requires
- - style_type == a type that inherits from button_style
- ensures
- - this button object will draw itself using the given
- button style
- !*/
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the button is
- clicked by the user.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_click_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the button is clicked by
- the user.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler)(button& self)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - &self == this
- - the event_handler function is called on object when the button is
- clicked by the user.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_sourced_click_handler (
- const any_function<void(button& self)>& event_handler
- );
- /*!
- ensures
- - &self == this
- - the event_handler function is called when the button is clicked by
- the user.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_button_down_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the user causes
- the button to go into its depressed state.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_button_down_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the user causes the button
- to go into its depressed state.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_button_up_handler (
- T& object,
- void (T::*event_handler)(bool mouse_over)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the user causes
- the button to go into its non-depressed state.
- - if (the mouse is over this button when this event occurs) then
- - mouse_over == true
- - else
- - mouse_over == false
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_button_up_handler (
- const any_function<void(bool mouse_over)>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the user causes the
- button to go into its non-depressed state.
- - if (the mouse is over this button when this event occurs) then
- - mouse_over == true
- - else
- - mouse_over == false
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_button_down_handler (
- T& object,
- void (T::*event_handler)(button& self)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - &self == this
- - the event_handler function is called on object when the user causes
- the button to go into its depressed state.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_sourced_button_down_handler (
- const any_function<void(button& self)>& event_handler
- );
- /*!
- ensures
- - &self == this
- - the event_handler function is called when the user causes the button
- to go into its depressed state.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_button_up_handler (
- T& object,
- void (T::*event_handler)(bool mouse_over, button& self)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - &self == this
- - the event_handler function is called on object when the user causes
- the button to go into its non-depressed state.
- - if (the mouse is over this button when this event occurs) then
- - mouse_over == true
- - else
- - mouse_over == false
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_sourced_button_up_handler (
- const any_function<void(bool mouse_over, button& self)>& event_handler
- );
- /*!
- ensures
- - &self == this
- - the event_handler function is called when the user causes the
- button to go into its non-depressed state.
- - if (the mouse is over this button when this event occurs) then
- - mouse_over == true
- - else
- - mouse_over == false
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- button(button&); // copy constructor
- button& operator=(button&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class scroll_bar
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class scroll_bar : public drawable
- {
- /*!
- INITIAL VALUE
- orientation() == a value given to the constructor.
- max_slider_pos() == 0
- slider_pos() == 0
- jump_size() == 10
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a scroll bar. The slider_pos() of the scroll bar
- ranges from 0 to max_slider_pos(). The 0 position of the scroll_bar is
- in the top or left side of the scroll_bar depending on its orientation.
-
- When this object is disabled it means it will not respond to user clicks.
- !*/
-
- public:
- enum bar_orientation
- {
- HORIZONTAL,
- VERTICAL
- };
-
- scroll_bar(
- drawable_window& w,
- bar_orientation orientation
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #orientation() == orientation
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~scroll_bar(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- bar_orientation orientation (
- ) const;
- /*!
- ensures
- - returns the orientation of this scroll_bar
- !*/
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style
- );
- /*!
- requires
- - style_type == a type that inherits from scroll_bar_style
- ensures
- - this scroll_bar object will draw itself using the given
- scroll bar style
- !*/
-
- void set_length (
- unsigned long length,
- );
- /*!
- ensures
- - if (orientation() == HORIZONTAL) then
- - #width() == max(length,1)
- - else
- - #height() == max(length,1)
- !*/
-
- long max_slider_pos (
- ) const;
- /*!
- ensures
- - returns the maximum value that slider_pos() can take.
- !*/
-
- void set_max_slider_pos (
- long mpos
- );
- /*!
- ensures
- - if (mpos < 0) then
- - #max_slider_pos() == 0
- - else
- - #max_slider_pos() == mpos
- - if (slider_pos() > #max_slider_pos()) then
- - #slider_pos() == #max_slider_pos()
- - else
- - #slider_pos() == slider_pos()
- !*/
-
- void set_slider_pos (
- unsigned long pos
- );
- /*!
- ensures
- - if (pos < 0) then
- - #slider_pos() == 0
- - else if (pos > max_slider_pos()) then
- - #slider_pos() == max_slider_pos()
- - else
- - #slider_pos() == pos
- !*/
-
- long slider_pos (
- ) const;
- /*!
- ensures
- - returns the current position of the slider box within the scroll bar.
- !*/
-
- long jump_size (
- ) const;
- /*!
- ensures
- - returns the number of positions that the slider bar will jump when the
- user clicks on the empty gaps above or below the slider bar.
- (note that the slider will jump less than the jump size if it hits the
- end of the scroll bar)
- !*/
-
- void set_jump_size (
- long js
- );
- /*!
- ensures
- - if (js < 1) then
- - #jump_size() == 1
- - else
- - #jump_size() == js
- !*/
-
-
- template <
- typename T
- >
- void set_scroll_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - The event_handler function is called whenever the user causes the slider box
- to move.
- - This event is NOT triggered by calling set_slider_pos()
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_scroll_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - The event_handler function is called whenever the user causes the slider box
- to move.
- - This event is NOT triggered by calling set_slider_pos()
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- scroll_bar(scroll_bar&); // copy constructor
- scroll_bar& operator=(scroll_bar&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class widget_group
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class widget_group : public drawable
- {
- /*!
- INITIAL VALUE
- size() == 0
- get_rect().is_empty() == true
- left() == 0
- top() == 0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a grouping of drawable widgets. It doesn't draw
- anything itself, rather it lets you manipulate the position, enabled
- status, and visibility of a set of widgets as a group.
- !*/
-
- public:
- widget_group(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~widget_group(
- );
- /*!
- ensures
- - all resources associated with *this have been released.
- !*/
-
- void empty (
- );
- /*!
- ensures
- - #size() == 0
- !*/
-
- void fit_to_contents (
- );
- /*!
- ensures
- - does not change the position of this object.
- (i.e. the upper left corner of get_rect() remains at the same position)
- - if (size() == 0) then
- - #get_rect().is_empty() == true
- - else
- - recursively calls fit_to_contents() on any widget_groups inside
- this object.
- - #get_rect() will be the smallest rectangle that contains all the
- widgets in this group and the upper left corner of get_rect().
- !*/
-
- size_t size (
- ) const;
- /*!
- ensures
- - returns the number of widgets currently in *this.
- !*/
-
- void add (
- drawable& widget,
- unsigned long x,
- unsigned long y
- );
- /*!
- ensures
- - #is_member(widget) == true
- - if (is_member(widget) == false) then
- - #size() == size() + 1
- - else
- - #size() == size()
- - The following conditions apply to this function as well as to all of the
- following functions so long as is_member(widget) == true:
- enable(), disable(), hide(), show(), set_z_order(), and set_pos().
- - #widget.left() == left()+x
- - #widget.width() == widget.width()
- - #widget.top() == top()+y
- - #widget.height() == widget.height()
- - #widget.is_hidden() == is_hidden()
- - #widget.is_enabled() == is_enabled()
- - #widget.z_order() == z_order()
- throws
- - std::bad_alloc
- !*/
-
- bool is_member (
- const drawable& widget
- ) const;
- /*!
- ensures
- - returns true if widget is currently in this object, returns false otherwise.
- !*/
-
- void remove (
- const drawable& widget
- );
- /*!
- ensures
- - #is_member(widget) == false
- - if (is_member(widget) == true) then
- - #size() == size() - 1
- - else
- - #size() == size()
- !*/
-
- protected:
-
- // this object doesn't draw anything but also isn't abstract
- void draw (
- const canvas& c
- ) const {}
-
- private:
-
- // restricted functions
- widget_group(widget_group&); // copy constructor
- widget_group& operator=(widget_group&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class image_widget
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class image_widget : public draggable
- {
- /*!
- INITIAL VALUE
- draggable_area() == an initial value for its type.
- This object isn't displaying anything.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a draggable image. You give it an image to display
- by calling set_image().
-
- Also note that initially the draggable area is empty so it won't be
- draggable unless you call set_draggable_area() to some non-empty region.
-
- The image is drawn such that:
- - the pixel img[0][0] is the upper left corner of the image.
- - the pixel img[img.nr()-1][0] is the lower left corner of the image.
- - the pixel img[0][img.nc()-1] is the upper right corner of the image.
- - the pixel img[img.nr()-1][img.nc()-1] is the lower right corner of the image.
-
- !*/
-
- public:
-
- image_widget(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~image_widget(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- template <
- typename image_type
- >
- void set_image (
- const image_type& img
- );
- /*!
- requires
- - image_type == an implementation of array2d/array2d_kernel_abstract.h
- - pixel_traits<typename image_type::type> must be defined
- ensures
- - #width() == img.nc()
- - #height() == img.nr()
- - #*this widget is now displaying the given image img.
- !*/
-
- private:
-
- // restricted functions
- image_widget(image_widget&); // copy constructor
- image_widget& operator=(image_widget&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class tooltip
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class tooltip : public mouse_over_event
- {
- /*!
- INITIAL VALUE
- - text() == ""
- - the tooltip is inactive until the text is changed to
- a non-empty string.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a region on a window where if the user
- hovers the mouse over this region a tooltip with a message
- appears.
- !*/
-
- public:
-
- tooltip(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~tooltip(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_size (
- unsigned long width_,
- unsigned long height_
- );
- /*!
- ensures
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this widget stays the
- same but its width and height are modified
- !*/
-
- void set_text (const std::wstring& str);
- void set_text (const dlib::ustring& str);
- void set_text (
- const std::string& str
- );
- /*!
- ensures
- - #text() == str
- - activates the tooltip. i.e. after this function the tooltip
- will display on the screen when the user hovers the mouse over it
- !*/
-
- const std::wstring wtext () const;
- const dlib::ustring utext () const;
- const std::string text (
- ) const;
- /*!
- ensures
- - returns the text that is displayed inside this
- tooltip
- !*/
-
- private:
-
- // restricted functions
- tooltip(tooltip&); // copy constructor
- tooltip& operator=(tooltip&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // popup menu stuff
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class menu_item
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an abstract class that defines the interface a
- menu item in a popup_menu must implement.
-
- Note that a menu_item is drawn as 3 separate pieces:
- ---------------------------------
- | left | middle | right |
- ---------------------------------
-
- Also note that derived classes must be copyable via
- their copy constructors.
- !*/
-
- public:
-
- virtual ~menu_item() {}
-
- virtual void on_click (
- ) const {}
- /*!
- requires
- - the mutex drawable::m is locked
- - if (has_click_event()) then
- - this function is called when the user clicks on this menu_item
- !*/
-
- virtual bool has_click_event (
- ) const { return false; }
- /*!
- ensures
- - if (this menu_item wants to receive on_click events) then
- - returns true
- - else
- - returns false
- !*/
-
- virtual unichar get_hot_key (
- ) const { return 0; }
- /*!
- ensures
- - if (this menu item has a keyboard hot key) then
- - returns the unicode value of the key
- - else
- - returns 0
- !*/
-
- virtual rectangle get_left_size (
- ) const { return rectangle(); } // return empty rect by default
- /*!
- ensures
- - returns the dimensions of the left part of the menu_item
- !*/
-
- virtual rectangle get_middle_size (
- ) const = 0;
- /*!
- ensures
- - returns the dimensions of the middle part of the menu_item
- !*/
-
- virtual rectangle get_right_size (
- ) const { return rectangle(); } // return empty rect by default
- /*!
- ensures
- - returns the dimensions of the right part of the menu_item
- !*/
-
- virtual void draw_background (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool is_selected
- ) const {}
- /*!
- requires
- - the mutex drawable::m is locked
- requires
- - c == the canvas to draw on
- - rect == the rectangle in which we are to draw the background
- - enabled == true if the menu_item is to be drawn enabled
- - is_selected == true if the menu_item is to be drawn selected
- ensures
- - draws the background of the menu_item on the canvas c at the location
- given by rect.
- !*/
-
- virtual void draw_left (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool is_selected
- ) const {}
- /*!
- requires
- - the mutex drawable::m is locked
- requires
- - c == the canvas to draw on
- - rect == the rectangle in which we are to draw the background
- - enabled == true if the menu_item is to be drawn enabled
- - is_selected == true if the menu_item is to be drawn selected
- ensures
- - draws the left part of the menu_item on the canvas c at the location
- given by rect.
- !*/
-
- virtual void draw_middle (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool is_selected
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- requires
- - c == the canvas to draw on
- - rect == the rectangle in which we are to draw the background
- - enabled == true if the menu_item is to be drawn enabled
- - is_selected == true if the menu_item is to be drawn selected
- ensures
- - draws the middle part of the menu_item on the canvas c at the location
- given by rect.
- !*/
-
- virtual void draw_right (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const bool is_selected
- ) const {}
- /*!
- requires
- - the mutex drawable::m is locked
- requires
- - c == the canvas to draw on
- - rect == the rectangle in which we are to draw the background
- - enabled == true if the menu_item is to be drawn enabled
- - is_selected == true if the menu_item is to be drawn selected
- ensures
- - draws the right part of the menu_item on the canvas c at the location
- given by rect.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class menu_item_text : public menu_item
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object is a simple text menu item
- !*/
-
- public:
-
- template <
- typename T
- >
- menu_item_text (
- const std::string& str,
- T& object,
- void (T::*on_click_handler)(),
- unichar hotkey = 0
- );
- /*!
- ensures
- - The text of this menu item will be str
- - the on_click_handler function is called on object when this menu_item
- clicked by the user.
- - #get_hot_key() == hotkey
- !*/
-
- menu_item_text (
- const std::string& str,
- const any_function<void()>& on_click_handler,
- unichar hotkey = 0
- );
- /*!
- ensures
- - The text of this menu item will be str
- - the on_click_handler function is called when this menu_item
- clicked by the user.
- - #get_hot_key() == hotkey
- !*/
-
- // overloads for wide character strings
- template <
- typename T
- >
- menu_item_text (
- const std::wstring& str,
- T& object,
- void (T::*on_click_handler)(),
- unichar hotkey = 0
- );
-
- menu_item_text (
- const std::wstring& str,
- const any_function<void()>& on_click_handler,
- unichar hotkey = 0
- );
-
- template <
- typename T
- >
- menu_item_text (
- const dlib::ustring& str,
- T& object,
- void (T::*on_click_handler)(),
- unichar hotkey = 0
- );
-
- template <
- typename T
- >
- menu_item_text (
- const dlib::ustring& str,
- const any_function<void()>& on_click_handler,
- unichar hotkey = 0
- );
- };
-
-// ----------------------------------------------------------------------------------------
-
- class menu_item_submenu : public menu_item
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object is a simple text item intended to be used with
- submenus inside a popup_menu.
- !*/
-
- public:
-
- menu_item_submenu (
- const std::string& str,
- unichar hotkey = 0
- );
- /*!
- ensures
- - The text of this menu item will be str
- - #get_hot_key() == hotkey
- !*/
-
- //overloads for wide character strings
- menu_item_submenu (
- const std::wstring& str,
- unichar hotkey = 0
- );
-
- menu_item_submenu (
- const dlib::ustring& str,
- unichar hotkey = 0
- );
- };
-
-// ----------------------------------------------------------------------------------------
-
- class menu_item_separator : public menu_item
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object is a horizontal separator in a popup menu
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class popup_menu : public base_window
- {
- /*!
- INITIAL VALUE
- - size() == 0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a popup menu window capable of containing
- menu_item objects.
- !*/
-
- public:
-
- popup_menu (
- );
- /*!
- ensures
- - #*this is properly initialized
- throws
- - std::bad_alloc
- - dlib::thread_error
- - dlib::gui_error
- !*/
-
- void clear (
- );
- /*!
- ensures
- - #*this has its initial value
- throws
- - std::bad_alloc
- if this exception is thrown then *this is unusable
- until clear() is called and succeeds
- !*/
-
- template <
- typename menu_item_type
- >
- unsigned long add_menu_item (
- const menu_item_type& new_item
- );
- /*!
- requires
- - menu_item_type == a type that inherits from menu_item
- ensures
- - adds new_item onto the bottom of this popup_menu.
- - returns size()
- (This is also the index by which this item can be
- referenced by the enable_menu_item() and disable_menu_item()
- functions.)
- !*/
-
- template <
- typename menu_item_type
- >
- unsigned long add_submenu (
- const menu_item_type& new_item,
- popup_menu& submenu
- );
- /*!
- requires
- - menu_item_type == a type that inherits from menu_item
- ensures
- - adds new_item onto the bottom of this popup_menu.
- - when the user puts the mouse above this menu_item the given
- submenu popup_menu will be displayed.
- - returns size()
- (This is also the index by which this item can be
- referenced by the enable_menu_item() and disable_menu_item()
- functions.)
- !*/
-
- void enable_menu_item (
- unsigned long idx
- );
- /*!
- requires
- - idx < size()
- ensures
- - the menu_item in this with the index idx has been enabled
- !*/
-
- void disable_menu_item (
- unsigned long idx
- );
- /*!
- requires
- - idx < size()
- ensures
- - the menu_item in this with the index idx has been disabled
- !*/
-
- size_t size (
- ) const;
- /*!
- ensures
- - returns the number of menu_item objects in this popup_menu
- !*/
-
- template <typename T>
- void set_on_hide_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- ensures
- - the event_handler function is called on object when this popup_menu
- hides itself due to an action by the user.
- - Note that you can register multiple handlers for this event.
- !*/
-
- void select_first_item (
- );
- /*!
- ensures
- - causes this popup menu to highlight the first
- menu item that it contains which has a click event
- and is enabled.
- !*/
-
- bool forwarded_on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
- /*!
- requires
- - key, is_printable, and state are the variables from the
- base_window::on_keydown() event
- ensures
- - forwards this keyboard event to this popup window so that it
- may deal with keyboard events from other windows.
- - if (this popup_menu uses the keyboard event) then
- - returns true
- - else
- - returns false
- !*/
-
- private:
-
- // restricted functions
- popup_menu(popup_menu&); // copy constructor
- popup_menu& operator=(popup_menu&); // assignment operator
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class popup_menu_region
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class popup_menu_region : public drawable
- {
- /*!
- INITIAL VALUE
- - popup_menu_visible() == false
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a region on a window where if the user
- right clicks the mouse over this region a popup_menu pops up.
-
- Note that this widget doesn't actually draw anything, it just
- provides a region the user can click on to get a popup menu.
- !*/
-
- public:
-
- popup_menu_region(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~popup_menu_region(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_size (
- unsigned long width_,
- unsigned long height_
- );
- /*!
- ensures
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this widget stays the
- same but its width and height are modified
- !*/
-
- void set_rect (
- const rectangle& new_rect
- );
- /*!
- ensures
- - #get_rect() == new_rect
- !*/
-
- bool popup_menu_visible (
- ) const;
- /*!
- ensures
- - if (the popup menu is currently visible on the screen) then
- - returns true
- - else
- - returns false
- !*/
-
- popup_menu& menu (
- );
- /*!
- ensures
- - returns a reference to the popup_menu for this object. It is
- the menu that is displayed when the user right clicks on
- this widget
- !*/
-
- private:
-
- // restricted functions
- popup_menu_region(popup_menu_region&); // copy constructor
- popup_menu_region& operator=(popup_menu_region&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class zoomable_region
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class zoomable_region : public drawable
- {
- /*
- INITIAL VALUE
- - min_zoom_scale() == 0.15
- - max_zoom_scale() == 1.0
- - zoom_increment() == 0.90
- - zoom_scale() == 1.0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a 2D Cartesian graph that you can zoom into and
- out of. It is a graphical widget that draws a rectangle with
- a horizontal and vertical scroll bar that allow the user to scroll
- around on a Cartesian graph that is much larger than the actual
- area occupied by this object on the screen. It also allows
- the user to zoom in and out.
-
- To use this object you inherit from it and make use of its public and
- protected member functions. It provides functions for converting between
- pixel locations and the points in our 2D Cartesian graph so that when the
- user is scrolling/zooming the widget you can still determine where
- things are to be placed on the screen and what screen pixels correspond
- to in the Cartesian graph.
-
- Note that the Cartesian graph in this object is bounded by the point
- (0,0), corresponding to the upper left corner when we are zoomed all
- the way out, and max_graph_point() which corresponds to the lower right
- corner when zoomed all the way out. The value of max_graph_point() is
- determined automatically from the size of this object's on screen
- rectangle and the value of min_zoom_scale() which determines how far
- out you can zoom.
- */
-
- public:
-
- zoomable_region (
- drawable_window& w,
- unsigned long events = 0
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- - This object will not receive any events or draw() requests until
- enable_events() is called
- - the events flags are passed on to the drawable object's
- constructor.
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~zoomable_region (
- ) = 0;
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- );
- /*!
- requires
- - style_type == a type that inherits from scrollable_region_style
- ensures
- - this zoomable_region object will draw itself using the given
- style
- !*/
-
- void set_zoom_increment (
- double zi
- );
- /*!
- requires
- - 0 < zi < 1
- ensures
- - #zoom_increment() == zi
- !*/
-
- double zoom_increment (
- ) const;
- /*!
- ensures
- - When the user zooms in using the mouse wheel:
- - #zoom_scale() == zoom_scale() / zoom_increment()
- - When the user zooms out using the mouse wheel:
- - #zoom_scale() == zoom_scale() * zoom_increment()
- - So this function returns the number that determines how much the zoom
- changes when the mouse wheel is moved.
- !*/
-
- void set_max_zoom_scale (
- double ms
- );
- /*!
- requires
- - ms > 0
- ensures
- - #max_zoom_scale() == ms
- !*/
-
- void set_min_zoom_scale (
- double ms
- );
- /*!
- requires
- - ms > 0
- ensures
- - #min_zoom_scale() == ms
- !*/
-
- double min_zoom_scale (
- ) const;
- /*!
- ensures
- - returns the minimum allowed value of zoom_scale()
- (i.e. this is the number that determines how far out the user is allowed to zoom)
- !*/
-
- double max_zoom_scale (
- ) const;
- /*!
- ensures
- - returns the maximum allowed value of zoom_scale()
- (i.e. this is the number that determines how far in the user is allowed to zoom)
- !*/
-
- virtual void set_size (
- unsigned long width,
- unsigned long height
- );
- /*!
- ensures
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this button stays the
- same but its width and height are modified
- !*/
-
- protected:
-
- rectangle display_rect (
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - returns the rectangle on the screen that contains the Cartesian
- graph in this widget. I.e. this is the area of this widget minus
- the area taken up by the scroll bars and border decorations.
- !*/
-
- point graph_to_gui_space (
- const vector<double,2>& graph_point
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - returns the location of the pixel on the screen that corresponds
- to the given point in Cartesian graph space
- !*/
-
- vector<double,2> gui_to_graph_space (
- const point& pixel_point
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - returns the point in Cartesian graph space that corresponds to the given
- pixel location
- !*/
-
- vector<double,2> max_graph_point (
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - returns the pixel farthest from the graph point (0,0) that is still
- in the graph. I.e. returns the point in graph space that corresponds
- to the lower right corner of the display_rect() when we are zoomed
- all the way out.
- !*/
-
- double zoom_scale (
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - returns a double Z that represents the current zoom.
- - Smaller values of Z represent the user zooming out.
- - Bigger values of Z represent the user zooming in.
- - The default unzoomed case is when Z == 1
- - objects should be drawn such that they are zoom_scale()
- times their normal size
- !*/
-
- void set_zoom_scale (
- double new_scale
- );
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - invalidates the display_rect() so that it will be redrawn
- - if (min_zoom_scale() <= new_scale && new_scale <= max_zoom_scale()) then
- - #zoom_scale() == new_scale
- - else if (new_scale < min_zoom_scale()) then
- - #zoom_scale() == min_zoom_scale()
- - else if (new_scale > max_zoom_scale()) then
- - #zoom_scale() == max_zoom_scale()
- !*/
-
- void center_display_at_graph_point (
- const vector<double,2>& graph_point
- );
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - causes the given graph point to be centered in the display
- if possible
- - invalidates the display_rect() so that it will be redrawn
- !*/
-
- virtual void on_view_changed (
- ) {}
- /*!
- requires
- - events_are_enabled() == true
- - mutex drawable::m is locked
- ensures
- - on_view_changed() is called whenever the user causes the view of the
- zoomable_region to change. That is, this function is called when the
- user scrolls or zooms around in the region.
- !*/
-
- // ---------------------------- event handlers ----------------------------
- // The following event handlers are used in this object. So if you
- // use any of them in your derived object you should pass the events
- // back to it so that they still operate unless you wish to hijack the
- // event for your own reasons (e.g. to override the mouse drag this object
- // performs)
-
- void on_wheel_down (unsigned long state);
- void on_wheel_up (unsigned long state);
- void on_mouse_move ( unsigned long state, long x, long y);
- void on_mouse_up ( unsigned long btn, unsigned long state, long x, long y);
- void on_mouse_down ( unsigned long btn, unsigned long state, long x, long y, bool is_double_click);
- void draw ( const canvas& c) const;
-
- private:
-
- // restricted functions
- zoomable_region(zoomable_region&); // copy constructor
- zoomable_region& operator=(zoomable_region&); // assignment operator
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class scrollable_region : public drawable
- {
- /*!
- INITIAL VALUE
- - horizontal_scroll_pos() == 0
- - horizontal_scroll_increment() == 1
- - horizontal_mouse_wheel_scroll_increment() == 1
- - vertical_scroll_pos() == 0
- - vertical_scroll_increment() == 1
- - vertical_mouse_wheel_scroll_increment() == 1
- - total_rect().empty() == true
- - mouse_drag_enabled() == false
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a 2D region of arbitrary size that is displayed
- within a possibly smaller scrollable gui widget. That is, it is a
- graphical widget that draws a rectangle with a horizontal and vertical
- scroll bar that allows the user to scroll around on a region that is much
- larger than the actual area occupied by this object on the screen.
-
- To use this object you inherit from it and make use of its public and
- protected member functions. It provides a function, total_rect(), that
- tells you where the 2D region is on the screen. You draw your stuff
- inside total_rect() as you would normally except that you only modify
- pixels that are also inside display_rect(). When the user moves the
- scroll bars the position of total_rect() is updated accordingly, causing
- the widget's content to scroll across the screen.
- !*/
-
- public:
- scrollable_region (
- drawable_window& w,
- unsigned long events = 0
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- - This object will not receive any events or draw() requests until
- enable_events() is called
- - the events flags are passed on to the drawable object's
- constructor.
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~scrollable_region (
- ) = 0;
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- );
- /*!
- requires
- - style_type == a type that inherits from scrollable_region_style
- ensures
- - this scrollable_region object will draw itself using the given
- style
- !*/
-
- virtual void set_size (
- unsigned long width,
- unsigned long height
- );
- /*!
- ensures
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this widget stays the
- same but its width and height are modified.
- !*/
-
- long horizontal_scroll_pos (
- ) const;
- /*!
- ensures
- - returns the current position of the horizontal scroll bar.
- 0 means it is at the far left while bigger values represent
- scroll positions closer to the right.
- !*/
-
- long vertical_scroll_pos (
- ) const;
- /*!
- ensures
- - returns the current position of the vertical scroll bar.
- 0 means it is at the top and bigger values represent scroll positions
- closer to the bottom.
- !*/
-
- void set_horizontal_scroll_pos (
- long pos
- );
- /*!
- ensures
- - if (pos is a valid horizontal scroll position) then
- - #horizontal_scroll_pos() == pos
- - else
- - #horizontal_scroll_pos() == the valid scroll position closest to pos
- !*/
-
- void set_vertical_scroll_pos (
- long pos
- );
- /*!
- ensures
- - if (pos is a valid vertical scroll position) then
- - #vertical_scroll_pos() == pos
- - else
- - #vertical_scroll_pos() == the valid scroll position closest to pos
- !*/
-
- unsigned long horizontal_mouse_wheel_scroll_increment (
- ) const;
- /*!
- ensures
- - returns the number of positions the horizontal scroll bar
- moves when the user scrolls the mouse wheel.
- !*/
-
- unsigned long vertical_mouse_wheel_scroll_increment (
- ) const;
- /*!
- ensures
- - returns the number of positions the vertical scroll bar
- moves when the user scrolls the mouse wheel.
- !*/
-
- void set_horizontal_mouse_wheel_scroll_increment (
- unsigned long inc
- );
- /*!
- ensures
- - #horizontal_mouse_wheel_scroll_increment() == inc
- !*/
-
- void set_vertical_mouse_wheel_scroll_increment (
- unsigned long inc
- );
- /*!
- ensures
- - #vertical_mouse_wheel_scroll_increment() == inc
- !*/
-
-
- unsigned long horizontal_scroll_increment (
- ) const;
- /*!
- ensures
- - returns the number of pixels that total_rect() is moved by when
- the horizontal scroll bar moves by one position
- !*/
-
- unsigned long vertical_scroll_increment (
- ) const;
- /*!
- ensures
- - returns the number of pixels that total_rect() is moved by when
- the vertical scroll bar moves by one position
- !*/
-
- void set_horizontal_scroll_increment (
- unsigned long inc
- );
- /*!
- ensures
- - #horizontal_scroll_increment() == inc
- !*/
-
- void set_vertical_scroll_increment (
- unsigned long inc
- );
- /*!
- ensures
- - #vertical_scroll_increment() == inc
- !*/
-
- bool mouse_drag_enabled (
- ) const;
- /*!
- ensures
- - if (the user can drag this contents of this widget around by
- holding down the left mouse button and dragging) then
- - returns true
- - else
- - returns false
- !*/
-
- void enable_mouse_drag (
- );
- /*!
- ensures
- - #mouse_drag_enabled() == true
- !*/
-
- void disable_mouse_drag (
- );
- /*!
- ensures
- - #mouse_drag_enabled() == false
- !*/
-
- protected:
-
- rectangle display_rect (
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - returns the rectangle on the screen that contains the scrollable
- area in this widget. I.e. this is the area of this widget minus
- the area taken up by the scroll bars and border decorations.
- !*/
-
- void set_total_rect_size (
- unsigned long width,
- unsigned long height
- );
- /*!
- requires
- - mutex drawable::m is locked
- - (width > 0 && height > 0) || (width == 0 && height == 0)
- ensures
- - #total_rect().width() == width
- - #total_rect().height() == height
- - The scroll bars as well as the position of #total_rect()
- is updated so that the total rect is still in the correct
- position with respect to the scroll bars.
- !*/
-
- const rectangle& total_rect (
- ) const;
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - returns a rectangle that represents the entire scrollable
- region inside this widget, even the parts that are outside
- display_rect().
- !*/
-
- void scroll_to_rect (
- const rectangle& r
- );
- /*!
- requires
- - mutex drawable::m is locked
- ensures
- - Adjusts the scroll bars of this object so that the part of
- the total_rect() rectangle that overlaps with r is displayed in
- the display_rect() rectangle on the screen.
- !*/
-
- virtual void on_view_changed (
- ) {}
- /*!
- requires
- - events_are_enabled() == true
- - mutex drawable::m is locked
- ensures
- - on_view_changed() is called whenever the user causes the view of the
- scrollable_region to change. That is, this function is called when the
- user scrolls around in the region.
- !*/
-
- // ---------------------------- event handlers ----------------------------
- // The following event handlers are used in this object. So if you
- // use any of them in your derived object you should pass the events
- // back to it so that they still operate unless you wish to hijack the
- // event for your own reasons (e.g. to override the mouse wheel action
- // this object performs)
-
- void on_wheel_down (unsigned long state);
- void on_wheel_up (unsigned long state);
- void on_mouse_move (unsigned long state, long x, long y);
- void on_mouse_down (unsigned long btn, unsigned long state, long x, long y, bool is_double_click);
- void on_mouse_up (unsigned long btn, unsigned long state, long x, long y);
- void draw (const canvas& c) const;
-
- private:
-
- // restricted functions
- scrollable_region(scrollable_region&); // copy constructor
- scrollable_region& operator=(scrollable_region&); // assignment operator
-
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_BASE_WIDGETs_ABSTRACT_
-
-
diff --git a/ml/dlib/dlib/gui_widgets/canvas_drawing.cpp b/ml/dlib/dlib/gui_widgets/canvas_drawing.cpp
deleted file mode 100644
index 0fecd1cd3..000000000
--- a/ml/dlib/dlib/gui_widgets/canvas_drawing.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), and Nils Labugt
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_CANVAS_DRAWINg_CPP_
-#define DLIB_CANVAS_DRAWINg_CPP_
-
-#include "canvas_drawing.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- void draw_sunken_rectangle (
- const canvas& c,
- const rectangle& border,
- unsigned char alpha
- )
- {
- rectangle area = border.intersect(c);
- if (area.is_empty() == false)
- {
- const rgb_alpha_pixel dark_gray(64,64,64,alpha);
- const rgb_alpha_pixel gray(128,128,128,alpha);
- const rgb_alpha_pixel white(255,255,255,alpha);
- const rgb_alpha_pixel background(212,208,200,alpha);
-
- draw_line(c,point(border.left(),border.top()),point(border.right()-1,border.top()),gray);
-
- draw_line(c,point(border.left(),border.bottom()),point(border.right(),border.bottom()),white);
- draw_line(c,point(border.left()+1,border.bottom()-1),point(border.right()-1,border.bottom()-1),background);
-
- draw_line(c,point(border.left(),border.top()+1),point(border.left(),border.bottom()-1),gray);
-
- draw_line(c,point(border.right(),border.top()),point(border.right(),border.bottom()-1),white);
- draw_line(c,point(border.right()-1,border.top()+1),point(border.right()-1,border.bottom()-2),background);
-
- draw_line(c,point(border.left()+1,border.top()+1),point(border.left()+1,border.bottom()-2),dark_gray);
- draw_line(c,point(border.left()+1,border.top()+1),point(border.right()-2,border.top()+1),dark_gray);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void draw_button_down (
- const canvas& c,
- const rectangle& btn,
- unsigned char alpha
- )
- {
- rectangle area = btn.intersect(c);
- if (area.is_empty() == false)
- {
- const rgb_alpha_pixel dark_gray(64,64,64,alpha);
- const rgb_alpha_pixel gray(128,128,128,alpha);
- const rgb_alpha_pixel black(0,0,0,alpha);
-
- draw_line(c,point(btn.left(),btn.top()),point(btn.right(),btn.top()),black);
-
- draw_line(c,point(btn.left()+1,btn.bottom()),point(btn.right(),btn.bottom()),dark_gray);
- draw_line(c,point(btn.left()+1,btn.top()+1),point(btn.right()-1,btn.top()+1),gray);
-
- draw_line(c,point(btn.left(),btn.top()+1),point(btn.left(),btn.bottom()),black);
-
- draw_line(c,point(btn.right(),btn.top()+1),point(btn.right(),btn.bottom()-1),dark_gray);
- draw_line(c,point(btn.left()+1,btn.top()+1),point(btn.left()+1,btn.bottom()-1),gray);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void draw_button_up (
- const canvas& c,
- const rectangle& btn,
- unsigned char alpha
- )
- {
- rectangle area = btn.intersect(c);
- if (area.is_empty() == false)
- {
- const rgb_alpha_pixel dark_gray(64,64,64,alpha);
- const rgb_alpha_pixel gray(128,128,128,alpha);
- const rgb_alpha_pixel white(255,255,255,alpha);
-
- draw_line(c,point(btn.left(),btn.top()),point(btn.right()-1,btn.top()),white);
-
- draw_line(c,point(btn.left(),btn.bottom()),point(btn.right(),btn.bottom()),dark_gray);
- draw_line(c,point(btn.left()+1,btn.bottom()-1),point(btn.right()-1,btn.bottom()-1),gray);
-
- draw_line(c,point(btn.left(),btn.top()+1),point(btn.left(),btn.bottom()-1),white);
-
- draw_line(c,point(btn.right(),btn.top()),point(btn.right(),btn.bottom()-1),dark_gray);
- draw_line(c,point(btn.right()-1,btn.top()+1),point(btn.right()-1,btn.bottom()-2),gray);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_CANVAS_DRAWINg_CPP_
-
diff --git a/ml/dlib/dlib/gui_widgets/canvas_drawing.h b/ml/dlib/dlib/gui_widgets/canvas_drawing.h
deleted file mode 100644
index 61f688112..000000000
--- a/ml/dlib/dlib/gui_widgets/canvas_drawing.h
+++ /dev/null
@@ -1,964 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), and Nils Labugt
-// License: Boost Software License See LICENSE.txt for the full license.
-
-#ifndef DLIB_GUI_CANVAS_DRAWINg_
-#define DLIB_GUI_CANVAS_DRAWINg_
-
-#include "canvas_drawing_abstract.h"
-#include "../gui_core.h"
-#include "../algs.h"
-#include "../array2d.h"
-#include "../pixel.h"
-#include "../image_transforms/assign_image.h"
-#include "../geometry.h"
-#include <cmath>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void draw_line (
- const canvas& c,
- const point& p1,
- const point& p2,
- const pixel_type& pixel,
- const rectangle& area = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- rectangle valid_area(c.intersect(area));
- long x1 = p1.x();
- long y1 = p1.y();
- long x2 = p2.x();
- long y2 = p2.y();
- if (x1 == x2)
- {
- // if the x coordinate is inside the canvas's area
- if (x1 <= valid_area.right() && x1 >= valid_area.left())
- {
- // make sure y1 comes before y2
- if (y1 > y2)
- swap(y1,y2);
-
- y1 = std::max(y1,valid_area.top());
- y2 = std::min(y2,valid_area.bottom());
- // this is a vertical line
- for (long y = y1; y <= y2; ++y)
- {
- assign_pixel(c[y-c.top()][x1-c.left()], pixel);
- }
- }
- }
- else if (y1 == y2)
- {
- // if the y coordinate is inside the canvas's area
- if (y1 <= valid_area.bottom() && y1 >= valid_area.top())
- {
- // make sure x1 comes before x2
- if (x1 > x2)
- swap(x1,x2);
-
- x1 = std::max(x1,valid_area.left());
- x2 = std::min(x2,valid_area.right());
- // this is a horizontal line
- for (long x = x1; x <= x2; ++x)
- {
- assign_pixel(c[y1-c.top()][x-c.left()], pixel);
- }
- }
- }
- else
- {
- rgb_alpha_pixel alpha_pixel;
- assign_pixel(alpha_pixel, pixel);
- const unsigned char max_alpha = alpha_pixel.alpha;
-
- const long rise = (((long)y2) - ((long)y1));
- const long run = (((long)x2) - ((long)x1));
- if (std::abs(rise) < std::abs(run))
- {
- const double slope = ((double)rise)/run;
-
- double first, last;
-
- if (x1 > x2)
- {
- first = std::max(x2,valid_area.left());
- last = std::min(x1,valid_area.right());
- }
- else
- {
- first = std::max(x1,valid_area.left());
- last = std::min(x2,valid_area.right());
- }
-
-
- long y;
- long x;
- const double x1f = x1;
- const double y1f = y1;
- for (double i = first; i <= last; ++i)
- {
- const double dy = slope*(i-x1f) + y1f;
- const double dx = i;
-
- y = static_cast<long>(dy);
- x = static_cast<long>(dx);
-
-
- if (y >= valid_area.top() && y <= valid_area.bottom())
- {
- alpha_pixel.alpha = static_cast<unsigned char>((1.0-(dy-y))*max_alpha);
- assign_pixel(c[y-c.top()][x-c.left()], alpha_pixel);
- }
- if (y+1 >= valid_area.top() && y+1 <= valid_area.bottom())
- {
- alpha_pixel.alpha = static_cast<unsigned char>((dy-y)*max_alpha);
- assign_pixel(c[y+1-c.top()][x-c.left()], alpha_pixel);
- }
- }
- }
- else
- {
- const double slope = ((double)run)/rise;
-
- double first, last;
-
- if (y1 > y2)
- {
- first = std::max(y2,valid_area.top());
- last = std::min(y1,valid_area.bottom());
- }
- else
- {
- first = std::max(y1,valid_area.top());
- last = std::min(y2,valid_area.bottom());
- }
-
- long x;
- long y;
- const double x1f = x1;
- const double y1f = y1;
- for (double i = first; i <= last; ++i)
- {
- const double dx = slope*(i-y1f) + x1f;
- const double dy = i;
-
- y = static_cast<long>(dy);
- x = static_cast<long>(dx);
-
- if (x >= valid_area.left() && x <= valid_area.right())
- {
- alpha_pixel.alpha = static_cast<unsigned char>((1.0-(dx-x))*max_alpha);
- assign_pixel(c[y-c.top()][x-c.left()], alpha_pixel);
- }
- if (x+1 >= valid_area.left() && x+1 <= valid_area.right())
- {
- alpha_pixel.alpha = static_cast<unsigned char>((dx-x)*max_alpha);
- assign_pixel(c[y-c.top()][x+1-c.left()], alpha_pixel);
- }
- }
- }
- }
-
- }
- inline void draw_line (
- const canvas& c,
- const point& p1,
- const point& p2
- ){ draw_line(c,p1,p2,0); }
-
-// ----------------------------------------------------------------------------------------
-
- void draw_sunken_rectangle (
- const canvas& c,
- const rectangle& border,
- unsigned char alpha = 255
- );
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- inline void draw_pixel (
- const canvas& c,
- const point& p,
- const pixel_type& pixel
- )
- {
- if (c.contains(p))
- {
- assign_pixel(c[p.y()-c.top()][p.x()-c.left()],pixel);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void draw_checkered (
- const canvas& c,
- const rectangle& a,
- const pixel_type& pixel1,
- const pixel_type& pixel2
- )
- {
- rectangle area = a.intersect(c);
- if (area.is_empty())
- return;
-
- for (long i = area.left(); i <= area.right(); ++i)
- {
- for (long j = area.top(); j <= area.bottom(); ++j)
- {
- canvas::pixel& p = c[j - c.top()][i - c.left()];
- if ((j&0x1) ^ (i&0x1))
- {
- assign_pixel(p,pixel1);
- }
- else
- {
- assign_pixel(p,pixel2);
- }
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void draw_button_down (
- const canvas& c,
- const rectangle& btn,
- unsigned char alpha = 255
- );
-
-// ----------------------------------------------------------------------------------------
-
- void draw_button_up (
- const canvas& c,
- const rectangle& btn,
- unsigned char alpha = 255
- );
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void draw_circle (
- const canvas& c,
- const point& center_point,
- double radius,
- const pixel_type& pixel,
- const rectangle& area = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- using std::sqrt;
- rectangle valid_area(c.intersect(area));
- const long x = center_point.x();
- const long y = center_point.y();
- if (radius > 1)
- {
- long first_x = static_cast<long>(x - radius + 0.5);
- long last_x = static_cast<long>(x + radius + 0.5);
- const double rs = radius*radius;
-
- // ensure that we only loop over the part of the x dimension that this
- // canvas contains.
- if (first_x < valid_area.left())
- first_x = valid_area.left();
- if (last_x > valid_area.right())
- last_x = valid_area.right();
-
- long top, bottom;
-
- top = static_cast<long>(sqrt(std::max(rs - (first_x-x-0.5)*(first_x-x-0.5),0.0))+0.5);
- top += y;
- long last = top;
-
- // draw the left half of the circle
- long middle = std::min(x-1,last_x);
- for (long i = first_x; i <= middle; ++i)
- {
- double a = i - x + 0.5;
- // find the top of the arc
- top = static_cast<long>(sqrt(std::max(rs - a*a,0.0))+0.5);
- top += y;
- long temp = top;
-
- while(top >= last)
- {
- bottom = y - top + y;
- if (top >= valid_area.top() && top <= valid_area.bottom() )
- {
- assign_pixel(c[top-c.top()][i-c.left()],pixel);
- }
-
- if (bottom >= valid_area.top() && bottom <= valid_area.bottom() )
- {
- assign_pixel(c[bottom-c.top()][i-c.left()],pixel);
- }
- --top;
- }
-
- last = temp;
- }
-
- middle = std::max(x,first_x);
- top = static_cast<long>(sqrt(std::max(rs - (last_x-x+0.5)*(last_x-x+0.5),0.0))+0.5);
- top += y;
- last = top;
- // draw the right half of the circle
- for (long i = last_x; i >= middle; --i)
- {
- double a = i - x - 0.5;
- // find the top of the arc
- top = static_cast<long>(sqrt(std::max(rs - a*a,0.0))+0.5);
- top += y;
- long temp = top;
-
- while(top >= last)
- {
- bottom = y - top + y;
- if (top >= valid_area.top() && top <= valid_area.bottom() )
- {
- assign_pixel(c[top-c.top()][i-c.left()],pixel);
- }
-
- if (bottom >= valid_area.top() && bottom <= valid_area.bottom() )
- {
- assign_pixel(c[bottom-c.top()][i-c.left()],pixel);
- }
- --top;
- }
-
- last = temp;
- }
- }
- else if (radius == 1 &&
- x >= valid_area.left() && x <= valid_area.right() &&
- y >= valid_area.top() && y <= valid_area.bottom() )
- {
- assign_pixel(c[y-c.top()][x-c.left()], pixel);
- }
- }
- inline void draw_circle (
- const canvas& c,
- const point& center_point,
- double radius
- ){ draw_circle(c, center_point, radius, 0); }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void draw_solid_circle (
- const canvas& c,
- const point& center_point,
- double radius,
- const pixel_type& pixel,
- const rectangle& area = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- using std::sqrt;
- rectangle valid_area(c.intersect(area));
- const long x = center_point.x();
- const long y = center_point.y();
- if (radius > 1)
- {
- long first_x = static_cast<long>(x - radius + 0.5);
- long last_x = static_cast<long>(x + radius + 0.5);
- const double rs = radius*radius;
-
- // ensure that we only loop over the part of the x dimension that this
- // canvas contains.
- if (first_x < valid_area.left())
- first_x = valid_area.left();
- if (last_x > valid_area.right())
- last_x = valid_area.right();
-
- long top, bottom;
-
- top = static_cast<long>(sqrt(std::max(rs - (first_x-x-0.5)*(first_x-x-0.5),0.0))+0.5);
- top += y;
- long last = top;
-
- // draw the left half of the circle
- long middle = std::min(x-1,last_x);
- for (long i = first_x; i <= middle; ++i)
- {
- double a = i - x + 0.5;
- // find the top of the arc
- top = static_cast<long>(sqrt(std::max(rs - a*a,0.0))+0.5);
- top += y;
- long temp = top;
-
- while(top >= last)
- {
- bottom = y - top + y;
- draw_line(c, point(i,top),point(i,bottom),pixel,area);
- --top;
- }
-
- last = temp;
- }
-
- middle = std::max(x,first_x);
- top = static_cast<long>(sqrt(std::max(rs - (last_x-x+0.5)*(last_x-x+0.5),0.0))+0.5);
- top += y;
- last = top;
- // draw the right half of the circle
- for (long i = last_x; i >= middle; --i)
- {
- double a = i - x - 0.5;
- // find the top of the arc
- top = static_cast<long>(sqrt(std::max(rs - a*a,0.0))+0.5);
- top += y;
- long temp = top;
-
- while(top >= last)
- {
- bottom = y - top + y;
- draw_line(c, point(i,top),point(i,bottom),pixel,area);
- --top;
- }
-
- last = temp;
- }
- }
- else if (radius == 1 &&
- x >= valid_area.left() && x <= valid_area.right() &&
- y >= valid_area.top() && y <= valid_area.bottom() )
- {
- assign_pixel(c[y-c.top()][x-c.left()], pixel);
- }
- }
- inline void draw_solid_circle (
- const canvas& c,
- const point& center_point,
- double radius
- ) { draw_solid_circle(c, center_point, radius, 0); }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
-
- template <typename alloc>
- void get_convex_polygon_shape (
- const std::vector<point>& points,
- const long top,
- const long bottom,
- std::vector<double,alloc>& left_boundary,
- std::vector<double,alloc>& right_boundary
- )
- /*!
- requires
- - 0 <= top <= bottom
- ensures
- - interprets points as the coordinates defining a convex polygon. In
- particular, we interpret points as a list of the vertices of the polygon
- and assume they are ordered in clockwise order.
- - #left_boundary.size() == bottom-top+1
- - #right_boundary.size() == bottom-top+1
- - for all top <= y <= bottom:
- - #left_boundary[y-top] == the x coordinate for the left most side of
- the polygon at coordinate y.
- - #right_boundary[y-top] == the x coordinate for the right most side of
- the polygon at coordinate y.
- !*/
- {
- using std::min;
- using std::max;
-
- left_boundary.assign(bottom-top+1, std::numeric_limits<double>::infinity());
- right_boundary.assign(bottom-top+1, -std::numeric_limits<double>::infinity());
-
- // trace out the points along the edge of the polynomial and record them
- for (unsigned long i = 0; i < points.size(); ++i)
- {
- const point p1 = points[i];
- const point p2 = points[(i+1)%points.size()];
-
- if (p1.y() == p2.y())
- {
- if (top <= p1.y() && p1.y() <= bottom)
- {
- const long y = p1.y() - top;
- const double xmin = min(p1.x(), p2.x());
- const double xmax = min(p1.x(), p2.x());
- left_boundary[y] = min(left_boundary[y], xmin);
- right_boundary[y] = max(right_boundary[y], xmax);
- }
- }
- else
- {
- // Here we trace out the line from p1 to p2 and record where it hits.
-
- // x = m*y + b
- const double m = (p2.x() - p1.x())/(double)(p2.y()-p1.y());
- const double b = p1.x() - m*p1.y(); // because: x1 = m*y1 + b
-
- const long ymin = max(top,min(p1.y(), p2.y()));
- const long ymax = min(bottom,max(p1.y(), p2.y()));
- for (long y = ymin; y <= ymax; ++y)
- {
- const double x = m*y + b;
- const unsigned long idx = y-top;
- left_boundary[idx] = min(left_boundary[idx], x);
- right_boundary[idx] = max(right_boundary[idx], x);
- }
- }
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
- template <typename pixel_type>
- void draw_solid_convex_polygon (
- const canvas& c,
- const std::vector<point>& polygon,
- const pixel_type& pixel,
- const rectangle& area = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- using std::max;
- using std::min;
- const rectangle valid_area(c.intersect(area));
-
- rectangle bounding_box;
- for (unsigned long i = 0; i < polygon.size(); ++i)
- bounding_box += polygon[i];
-
- // Don't do anything if the polygon is totally outside the area we can draw in
- // right now.
- if (bounding_box.intersect(valid_area).is_empty())
- return;
-
- rgb_alpha_pixel alpha_pixel;
- assign_pixel(alpha_pixel, pixel);
- const unsigned char max_alpha = alpha_pixel.alpha;
-
- // we will only want to loop over the part of left_boundary that is part of the
- // valid_area.
- long top = max(valid_area.top(),bounding_box.top());
- long bottom = min(valid_area.bottom(),bounding_box.bottom());
-
- // Since we look at the adjacent rows of boundary information when doing the alpha
- // blending, we want to make sure we always have some boundary information unless
- // we are at the absolute edge of the polygon.
- const long top_offset = (top == bounding_box.top()) ? 0 : 1;
- const long bottom_offset = (bottom == bounding_box.bottom()) ? 0 : 1;
- if (top != bounding_box.top())
- top -= 1;
- if (bottom != bounding_box.bottom())
- bottom += 1;
-
- std::vector<double> left_boundary;
- std::vector<double> right_boundary;
- impl::get_convex_polygon_shape(polygon, top, bottom, left_boundary, right_boundary);
-
-
- // draw the polygon row by row
- for (unsigned long i = top_offset; i < left_boundary.size(); ++i)
- {
- long left_x = static_cast<long>(std::ceil(left_boundary[i]));
- long right_x = static_cast<long>(std::floor(right_boundary[i]));
-
- left_x = max(left_x, valid_area.left());
- right_x = min(right_x, valid_area.right());
-
- if (i < left_boundary.size()-bottom_offset)
- {
- // draw the main body of the polygon
- for (long x = left_x; x <= right_x; ++x)
- {
- const long y = i+top;
- assign_pixel(c[y-c.top()][x-c.left()], pixel);
- }
- }
-
- if (i == 0)
- continue;
-
- // Now draw anti-aliased edges so they don't look all pixely.
-
- // Alpha blend the edges on the left side.
- double delta = left_boundary[i-1] - left_boundary[i];
- if (std::abs(delta) <= 1)
- {
- if (std::floor(left_boundary[i]) != left_x)
- {
- const point p(static_cast<long>(std::floor(left_boundary[i])), i+top);
- rgb_alpha_pixel temp = alpha_pixel;
- temp.alpha = max_alpha-static_cast<unsigned char>((left_boundary[i]-p.x())*max_alpha);
- if (valid_area.contains(p))
- assign_pixel(c[p.y()-c.top()][p.x()-c.left()],temp);
- }
- }
- else if (delta < 0) // on the bottom side
- {
- for (long x = static_cast<long>(std::ceil(left_boundary[i-1])); x < left_x; ++x)
- {
- const point p(x, i+top);
- rgb_alpha_pixel temp = alpha_pixel;
- temp.alpha = static_cast<unsigned char>((x-left_boundary[i-1])/std::abs(delta)*max_alpha);
- if (valid_area.contains(p))
- assign_pixel(c[p.y()-c.top()][p.x()-c.left()],temp);
- }
- }
- else // on the top side
- {
- const long old_left_x = static_cast<long>(std::ceil(left_boundary[i-1]));
- for (long x = left_x; x < old_left_x; ++x)
- {
- const point p(x, i+top-1);
- rgb_alpha_pixel temp = alpha_pixel;
- temp.alpha = static_cast<unsigned char>((x-left_boundary[i])/delta*max_alpha);
- if (valid_area.contains(p))
- assign_pixel(c[p.y()-c.top()][p.x()-c.left()],temp);
- }
- }
-
-
- // Alpha blend the edges on the right side
- delta = right_boundary[i-1] - right_boundary[i];
- if (std::abs(delta) <= 1)
- {
- if (std::ceil(right_boundary[i]) != right_x)
- {
- const point p(static_cast<long>(std::ceil(right_boundary[i])), i+top);
- rgb_alpha_pixel temp = alpha_pixel;
- temp.alpha = max_alpha-static_cast<unsigned char>((p.x()-right_boundary[i])*max_alpha);
- if (valid_area.contains(p))
- assign_pixel(c[p.y()-c.top()][p.x()-c.left()],temp);
- }
- }
- else if (delta < 0) // on the top side
- {
- for (long x = static_cast<long>(std::floor(right_boundary[i-1]))+1; x <= right_x; ++x)
- {
- const point p(x, i+top-1);
- rgb_alpha_pixel temp = alpha_pixel;
- temp.alpha = static_cast<unsigned char>((right_boundary[i]-x)/std::abs(delta)*max_alpha);
- if (valid_area.contains(p))
- assign_pixel(c[p.y()-c.top()][p.x()-c.left()],temp);
- }
- }
- else // on the bottom side
- {
- const long old_right_x = static_cast<long>(std::floor(right_boundary[i-1]));
- for (long x = right_x+1; x <= old_right_x; ++x)
- {
- const point p(x, i+top);
- rgb_alpha_pixel temp = alpha_pixel;
- temp.alpha = static_cast<unsigned char>((right_boundary[i-1]-x)/delta*max_alpha);
- if (valid_area.contains(p))
- assign_pixel(c[p.y()-c.top()][p.x()-c.left()],temp);
- }
- }
- }
- }
- inline void draw_solid_convex_polygon (
- const canvas& c,
- const std::vector<point>& polygon
- ) { draw_solid_convex_polygon(c, polygon, 0); }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename image_type
- >
- void draw_image (
- const canvas& c,
- const point& p,
- const image_type& img,
- const rectangle& area_ = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- const long x = p.x();
- const long y = p.y();
- rectangle rect(x,y,num_columns(img)+x-1,num_rows(img)+y-1);
- rectangle area = c.intersect(rect).intersect(area_);
- if (area.is_empty())
- return;
-
- for (long row = area.top(); row <= area.bottom(); ++row)
- {
- for (long col = area.left(); col <= area.right(); ++col)
- {
- assign_pixel(c[row-c.top()][col-c.left()], img[row-rect.top()][col-rect.left()]);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename image_type
- >
- void draw_image (
- const canvas& c,
- const rectangle& rect,
- const image_type& img,
- const rectangle& area_ = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- const rectangle area = c.intersect(rect).intersect(area_);
- if (area.is_empty() || num_columns(img) * num_rows(img) == 0)
- return;
-
- const matrix<long,1> x = matrix_cast<long>(round(linspace(0, num_columns(img)-1, rect.width())));
- const matrix<long,1> y = matrix_cast<long>(round(linspace(0, num_rows(img)-1, rect.height())));
-
- for (long row = area.top(); row <= area.bottom(); ++row)
- {
- const long r = y(row-rect.top());
- long cc = area.left() - rect.left();
- for (long col = area.left(); col <= area.right(); ++col)
- {
- assign_pixel(c[row-c.top()][col-c.left()], img[r][x(cc++)]);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void draw_rounded_rectangle (
- const canvas& c,
- const rectangle& rect,
- unsigned radius,
- const pixel_type& color,
- const rectangle& area_ = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- if ( rect.intersect ( c ).is_empty() )
- return;
-
- draw_line ( c, point(rect.left() + radius + 1, rect.bottom()),
- point(rect.right() - radius - 1, rect.bottom()), color,area_ );
-
- draw_line ( c, point(rect.left() + radius + 1, rect.top()),
- point(rect.right() - radius - 1, rect.top()), color,area_ );
-
- draw_line ( c, point(rect.left(), rect.top() + radius + 1),
- point(rect.left(), rect.bottom() - radius - 1), color,area_ );
-
- draw_line ( c, point(rect.right(), rect.top() + radius + 1),
- point(rect.right(), rect.bottom() - radius - 1), color,area_ );
-
- unsigned x = radius, y = 0, old_x = x;
-
- point p;
- while ( x > y )
- {
- p = point(rect.left() + radius - y, rect.top() + radius - x);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.right() - radius + y, rect.top() + radius - x);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.right() - radius + y, rect.bottom() - radius + x);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.left() + radius - y, rect.bottom() - radius + x);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.left() + radius - x, rect.top() + radius - y);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.right() - radius + x, rect.top() + radius - y);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.right() - radius + x, rect.bottom() - radius + y);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.left() + radius - x, rect.bottom() - radius + y);
- if (area_.contains(p)) draw_pixel (c, p , color );
- y++;
- old_x = x;
- x = square_root ( ( radius * radius - y * y ) * 4 ) / 2;
- }
-
- if ( x == y && old_x != x )
- {
- p = point(rect.left() + radius - y, rect.top() + radius - x);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.right() - radius + y, rect.top() + radius - x);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.right() - radius + y, rect.bottom() - radius + x);
- if (area_.contains(p)) draw_pixel (c, p , color );
- p = point(rect.left() + radius - y, rect.bottom() - radius + x);
- if (area_.contains(p)) draw_pixel (c, p , color );
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void fill_gradient_rounded (
- const canvas& c,
- const rectangle& rect,
- unsigned long radius,
- const pixel_type& top_color,
- const pixel_type& bottom_color,
- const rectangle& area = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
-
- )
- {
- rectangle valid_area(c.intersect(area.intersect(rect)));
- if ( valid_area.is_empty() )
- return;
-
-
- unsigned long m_prev = 0, m = radius, c_div = valid_area.height() - 1;
-
- const long c_top = valid_area.top();
- const long c_bottom = valid_area.bottom();
-
- for ( long y = c_top; y <= c_bottom;y++ )
- {
-
- unsigned long c_s = y - c_top;
-
- unsigned long c_t = c_bottom - y;
-
-
- if ( c_div == 0 )
- {
- // only a single round, just take the average color
- c_div = 2;
- c_s = c_t = 1;
- }
-
- rgb_alpha_pixel color;
- vector_to_pixel(color,
- ((pixel_to_vector<unsigned long>(top_color)*c_t + pixel_to_vector<unsigned long>(bottom_color)*c_s)/c_div));
-
- unsigned long s = y - rect.top();
-
- unsigned long t = rect.bottom() - y;
-
- if ( s < radius )
- {
- m = radius - square_root ( ( radius * radius - ( radius - s ) * ( radius - s ) ) * 4 ) / 2;
-
- if ( s == m && m + 1 < m_prev ) // these are hacks to remove distracting artefacts at small radii
- m++;
- }
- else if ( t < radius )
- {
- m = radius - square_root ( ( radius * radius - ( radius - t ) * ( radius - t ) ) * 4 ) / 2;
-
- if ( t == m && m == m_prev )
- m++;
- }
- else
- {
- m = 0;
- }
-
- m_prev = m;
-
- draw_line ( c, point(rect.left() + m, y),
- point(rect.right() - m, y), color, valid_area );
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void draw_rectangle (
- const canvas& c,
- rectangle rect,
- const pixel_type& pixel,
- const rectangle& area = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- // top line
- draw_line(c, point(rect.left(),rect.top()),
- point(rect.right(),rect.top()),
- pixel, area);
-
- // bottom line
- draw_line(c, point(rect.left(),rect.bottom()),
- point(rect.right(),rect.bottom()),
- pixel, area);
-
- // left line
- draw_line(c, point(rect.left(),rect.top()),
- point(rect.left(),rect.bottom()),
- pixel, area);
-
- // right line
- draw_line(c, point(rect.right(),rect.top()),
- point(rect.right(),rect.bottom()),
- pixel, area);
- }
- inline void draw_rectangle (
- const canvas& c,
- rectangle rect
- ){ draw_rectangle(c, rect, 0); }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void fill_rect (
- const canvas& c,
- const rectangle& rect,
- const pixel_type& pixel
- )
- {
- rectangle area = rect.intersect(c);
- for (long y = area.top(); y <= area.bottom(); ++y)
- {
- for (long x = area.left(); x <= area.right(); ++x)
- {
- assign_pixel(c[y-c.top()][x-c.left()], pixel);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename pixel_type>
- void fill_rect_with_vertical_gradient (
- const canvas& c,
- const rectangle& rect,
- const pixel_type& pixel_top,
- const pixel_type& pixel_bottom,
- const rectangle& area_ = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- )
- {
- rectangle area = rect.intersect(c).intersect(area_);
- pixel_type pixel;
-
- const long s = rect.bottom()-rect.top();
-
- for (long y = area.top(); y <= area.bottom(); ++y)
- {
- const long t = rect.bottom()-y;
- const long b = y-rect.top();
- vector_to_pixel(pixel,
- ((pixel_to_vector<long>(pixel_top)*t +
- pixel_to_vector<long>(pixel_bottom)*b)/s));
-
- for (long x = area.left(); x <= area.right(); ++x)
- {
- assign_pixel(c[y-c.top()][x-c.left()], pixel);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "canvas_drawing.cpp"
-#endif
-
-#endif // DLIB_GUI_CANVAS_DRAWINg_
-
diff --git a/ml/dlib/dlib/gui_widgets/canvas_drawing_abstract.h b/ml/dlib/dlib/gui_widgets/canvas_drawing_abstract.h
deleted file mode 100644
index e4a298c76..000000000
--- a/ml/dlib/dlib/gui_widgets/canvas_drawing_abstract.h
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), and Nils Labugt
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_GUI_CANVAS_DRAWINg_ABSTRACT_
-#ifdef DLIB_GUI_CANVAS_DRAWINg_ABSTRACT_
-
-#include "../gui_core.h"
-#include "../pixel.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void draw_line (
- const canvas& c,
- const point& p1,
- const point& p2,
- const pixel_type& pixel = rgb_pixel(0,0,0),
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - draws the part of the line from p1 to p1 that overlaps with
- the canvas and area onto the canvas.
- - Uses the given pixel color.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void draw_rectangle (
- const canvas& c,
- rectangle rect,
- const pixel_type& pixel = rgb_pixel(0,0,0),
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - Draws the part of the rectangle that overlaps with
- the canvas and area onto the canvas.
- - Uses the given pixel color.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void draw_circle (
- const canvas& c,
- const point& center_point,
- double radius,
- const pixel_type& pixel = rgb_pixel(0,0,0),
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - draws the part of the circle centered at center_point with the given radius
- that overlaps with the canvas and area onto the canvas.
- - Uses the given pixel color.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void draw_pixel (
- const canvas& c,
- const point& p,
- const pixel_type& pixel
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - if (c.contains(p)) then
- - sets the pixel in c that represents the point p to the
- given pixel color.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void draw_solid_circle (
- const canvas& c,
- const point& center_point,
- double radius,
- const pixel_type& pixel = rgb_pixel(0,0,0),
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - draws the part of the solid circle centered at center_point with the given
- radius that overlaps with the canvas and area onto the canvas.
- ("solid" means that the interior is also filled in with the given
- pixel color)
- - Uses the given pixel color.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void draw_solid_convex_polygon (
- const canvas& c,
- const std::vector<point>& polygon,
- const pixel_type& pixel = rgb_pixel(0,0,0),
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - Interprets the given std::vector polygon object as defining a convex polygon
- shape. In particular, the polygon is given by taking the points and drawing
- lines between them. That is, imagine drawing a line connecting polygon[i]
- and polygon[(i+1)%polygon.size()], for all valid i, and then filling in the
- interior of the polygon. That is what this function does.
- - When drawing the polygon, only the part of the polygon which overlaps both
- the given canvas and area rectangle is drawn.
- - Uses the given pixel color to draw the polygon.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- void draw_button_down (
- const canvas& c,
- const rectangle& btn,
- unsigned char alpha = 255
- );
- /*!
- requires
- - 0 <= alpha <= 255
- ensures
- - draws the border of a button onto canvas c:
- - the border will be that of a button that is depressed
- - only the part of the border that overlaps with the canvas object
- will be drawn.
- - the border will be for the button whose area is defined by the
- rectangle btn.
- - performs alpha blending such that the button is drawn with full opacity
- when alpha is 255 and fully transparent when alpha is 0.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- void draw_sunken_rectangle (
- const canvas& c,
- const rectangle& border,
- unsigned char alpha = 255
- );
- /*!
- requires
- - 0 <= alpha <= 255
- ensures
- - draws a sunken rectangle around the given border.
- (This is the type of border used for text_fields and
- check_boxes and the like).
- - performs alpha blending such that the rectangle is drawn with full opacity
- when alpha is 255 and fully transparent when alpha is 0.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- void draw_button_up (
- const canvas& c,
- const rectangle& btn,
- unsigned char alpha = 255
- );
- /*!
- requires
- - 0 <= alpha <= 255
- ensures
- - draws the border of a button onto canvas c:
- - the border will be that of a button that is NOT depressed
- - only the part of the border that overlaps with the canvas object
- will be drawn.
- - the border will be for the button whose area is defined by the
- rectangle btn.
- - performs alpha blending such that the button is drawn with full opacity
- when alpha is 255 and fully transparent when alpha is 0.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void draw_checkered (
- const canvas& c,
- const rectangle& area,
- const pixel_type& pixel1,
- const pixel_type& pixel2
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - fills the area on the given canvas defined by the rectangle area with a checkers
- board pattern where every other pixel gets assigned either pixel1 or pixel2.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename image_type
- >
- void draw_image (
- const canvas& c
- const point& p,
- const image_type& image,
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - image_type == an implementation of array2d/array2d_kernel_abstract.h
- - pixel_traits<typename image_type::type> is defined
- ensures
- - draws the given image object onto the canvas such that the upper left corner of the
- image will appear at the point p in the canvas's window. (note that the
- upper left corner of the image is assumed to be the pixel image[0][0] and the
- lower right corner of the image is assumed to be image[image.nr()-1][image.nc()-1])
- - only draws the part of the image that overlaps with the area rectangle
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename image_type
- >
- void draw_image (
- const canvas& c,
- const rectangle& rect,
- const image_type& img,
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - image_type == an implementation of array2d/array2d_kernel_abstract.h
- - pixel_traits<typename image_type::type> is defined
- ensures
- - draws the given image object onto the canvas such that the upper left corner
- of the image will appear at the point rect.tl_corner() in the canvas's window
- and the lower right corner of the image will appear at rect.br_corner() in
- the canvas's window. (note that the upper left corner of the image is
- assumed to be the pixel image[0][0] and the lower right corner of the image
- is assumed to be image[image.nr()-1][image.nc()-1])
- - only draws the part of the image that overlaps with the area rectangle
- - Uses nearest neighbor interpolation when the given rect isn't the same size
- as the input image.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void fill_rect (
- const canvas& c,
- const rectangle& rect,
- const pixel_type& pixel
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - fills the area defined by rect in the given canvas with the given pixel color.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void fill_rect_with_vertical_gradient (
- const canvas& c,
- const rectangle& rect,
- const pixel_type& pixel_top,
- const pixel_type& pixel_bottom,
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - fills the rectangle defined by rect in the given canvas with the given colors.
- The top of the area will have the pixel_top color and will slowly fade
- towards the pixel_bottom color towards the bottom of rect.
- - only draws the part of the image that overlaps with the area rectangle
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void fill_gradient_rounded (
- const canvas& c,
- const rectangle& rect,
- unsigned long radius,
- const pixel_type& top_color,
- const pixel_type& bottom_color,
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - Fills the region defined by rect in the given canvas with the given colors.
- The top of the region will have the top_color color and will slowly fade
- towards the bottom_color color towards the bottom of rect.
- - The drawn rectangle will have rounded corners and with the amount of
- - rounding given by the radius argument.
- - only the part of this object that overlaps with area and the canvas
- will be drawn on the canvas
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename pixel_type
- >
- void draw_rounded_rectangle (
- const canvas& c,
- const rectangle& rect,
- unsigned radius,
- const pixel_type& color,
- const rectangle& area = rectangle(-infinity,-infinity,infinity,infinity)
- );
- /*!
- requires
- - pixel_traits<pixel_type> is defined
- ensures
- - Draws the part of the rectangle that overlaps with
- the canvas onto the canvas.
- - The drawn rectangle will have rounded corners and with the amount of
- rounding given by the radius argument.
- - Uses the given pixel color.
- - only draws the part of the image that overlaps with the area rectangle
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_GUI_CANVAS_DRAWINg_ABSTRACT_
-
diff --git a/ml/dlib/dlib/gui_widgets/drawable.cpp b/ml/dlib/dlib/gui_widgets/drawable.cpp
deleted file mode 100644
index 8cf114950..000000000
--- a/ml/dlib/dlib/gui_widgets/drawable.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-// 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>
-#include <iostream>
-
-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 (
- )
- {
- 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 // DLIB_DRAWABLe_CPP_
-
diff --git a/ml/dlib/dlib/gui_widgets/drawable.h b/ml/dlib/dlib/gui_widgets/drawable.h
deleted file mode 100644
index a270b53c8..000000000
--- a/ml/dlib/dlib/gui_widgets/drawable.h
+++ /dev/null
@@ -1,527 +0,0 @@
-// 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_
-#define DLIB_DRAWABLe_
-
-#include <memory>
-
-#include "drawable_abstract.h"
-#include "../gui_core.h"
-#include "../set.h"
-#include "../binary_search_tree.h"
-#include "../algs.h"
-#include "../pixel.h"
-#include "fonts.h"
-#include "../matrix.h"
-#include "canvas_drawing.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class drawable_window
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class drawable;
- class drawable_window : public base_window
- {
- /*!
- INITIAL VALUE
- - lastx == -1
- - lasty == -1
- - event_id == 1
-
- CONVENTION
- - bg_color == background_color()
-
- - widgets == this binary search tree contains every drawable that is in
- this window. It is a mapping of each drawable's z-order to a pointer
- to said drawable.
- - widget_set == a set that contains all the widgets in this window and
- want to receive events.
-
- - mouse_move == this is a set of drawables that are in this window and
- want to receive the mouse movement events.
- - mouse_wheel == this is a set of drawables that are in this window and
- want to receive the mouse wheel events.
- - mouse_click == this is a set of drawables that are in this window and
- want to receive the mouse click events.
- - window_resized == this is a set of drawables that are in this window and
- want to receive the window_resized event.
- - keyboard == this is a set of drawables that are in this window and
- want to receive keyboard events.
- - focus == this is a set of drawables that are in this window and
- want to receive focus events.
- - window_moved == this is a set of drawables that are in this window and
- want to receive window move events.
-
- - lastx == the x coordinate that we last saw the mouse at or -1 if the
- mouse is outside this window.
- - lasty == the y coordinate that we last saw the mouse at or -1 if the
- mouse is outside this window.
-
- - event_id == a number we use to tag events so we don't end up sending
- an event to a drawable more than once. This could happen if one of the
- event handlers does something to reset the enumerator while we are
- dispatching events (e.g. creating a new widget).
- !*/
- public:
-
- drawable_window(
- bool resizable = true,
- bool undecorated = false
- ) :
- base_window(resizable,undecorated),
- bg_color(rgb_pixel(212,208,200)),
- lastx(-1),
- lasty(-1),
- event_id(1)
- {}
-
- void set_background_color (
- unsigned long red,
- unsigned long green,
- unsigned long blue
- );
-
- rgb_pixel background_color (
- ) const;
-
- virtual inline ~drawable_window()=0;
-
- private:
-
- void paint (
- const canvas& c
- );
-
- protected:
-
- void on_window_resized(
- );
-
- void on_window_moved(
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_leave (
- );
-
- void on_mouse_enter (
- );
-
- void on_wheel_up (
- unsigned long state
- );
-
- void on_wheel_down (
- unsigned long state
- );
-
- void on_focus_gained (
- );
-
- void on_focus_lost (
- );
-
- void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- void on_string_put (
- const std::wstring &str
- );
-
- void on_user_event (
- void* p,
- int i
- );
-
- private:
-
- friend class drawable;
-
-
- rgb_pixel bg_color;
-
- typedef set<drawable*>::kernel_1a_c set_of_drawables;
-
- binary_search_tree<long,set_of_drawables>::kernel_1a_c widgets;
-
- set_of_drawables widget_set;
- set_of_drawables mouse_move;
- set_of_drawables mouse_wheel;
- set_of_drawables mouse_click;
- set_of_drawables window_resized;
- set_of_drawables keyboard;
- set_of_drawables focus;
- set_of_drawables window_moved;
- set_of_drawables string_put;
-
- long lastx, lasty;
- unsigned long event_id;
-
-
- // restricted functions
- drawable_window(drawable_window&); // copy constructor
- drawable_window& operator=(drawable_window&); // assignment operator
-
-
- };
-
- drawable_window::~drawable_window(){ close_window();}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class drawable
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- enum
- {
- MOUSE_MOVE = 1,
- MOUSE_CLICK = 2,
- MOUSE_WHEEL = 4,
- WINDOW_RESIZED = 8,
- KEYBOARD_EVENTS = 16,
- FOCUS_EVENTS = 32,
- WINDOW_MOVED = 64,
- STRING_PUT = 128
- };
-
- class drawable
- {
-
- /*!
- INITIAL VALUE
- - enabled_events == false
- - event_id == 0
-
- CONVENTION
- - events == a bitset specifying what events this drawable is to receive.
-
- - z_order_value == z_order()
-
- - if (this drawable has been added to the parent window's sets and
- binary search tree) then
- - enabled_events == true
- - else
- - enabled_events == false
-
- - event_id == the id of the last event we got from our parent window
- !*/
-
- public:
-
- friend class drawable_window;
-
- drawable (
- drawable_window& w,
- unsigned long events_ = 0
- ) :
- m(w.wm),
- parent(w),
- hidden(false),
- enabled(true),
- lastx(w.lastx),
- lasty(w.lasty),
- mfont(default_font::get_font()),
- z_order_value(0),
- events(events_),
- enabled_events(false),
- event_id(0)
- {}
-
- virtual ~drawable (
- );
-
- long z_order (
- ) const
- {
- m.lock();
- long temp = z_order_value;
- m.unlock();
- return temp;
- }
-
- virtual void set_z_order (
- long order
- );
-
- const rectangle get_rect (
- ) const
- {
- auto_mutex M(m);
- return rect;
- }
-
- long bottom (
- ) const
- {
- auto_mutex M(m);
- return rect.bottom();
- }
-
- long top (
- ) const
- {
- auto_mutex M(m);
- return rect.top();
- }
-
- long left (
- ) const
- {
- auto_mutex M(m);
- return rect.left();
- }
-
- long right (
- ) const
- {
- auto_mutex M(m);
- return rect.right();
- }
-
- long width (
- ) const
- {
- auto_mutex M(m);
- return rect.width();
- }
-
- long height (
- ) const
- {
- auto_mutex M(m);
- return rect.height();
- }
-
- bool is_enabled (
- ) const
- {
- auto_mutex M(m);
- return enabled;
- }
-
- virtual void enable (
- )
- {
- auto_mutex M(m);
- enabled = true;
- parent.invalidate_rectangle(rect);
- }
-
- virtual void disable (
- )
- {
- auto_mutex M(m);
- enabled = false;
- parent.invalidate_rectangle(rect);
- }
-
- virtual void set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- parent.invalidate_rectangle(rect);
- }
-
- const std::shared_ptr<font> main_font (
- ) const
- {
- auto_mutex M(m);
- return mfont;
- }
-
- bool is_hidden (
- ) const
- {
- auto_mutex M(m);
- return hidden;
- }
-
- virtual void set_pos (
- long x,
- long y
- )
- {
- m.lock();
- rectangle old(rect);
-
- const unsigned long width = rect.width();
- const unsigned long height = rect.height();
- rect.set_top(y);
- rect.set_left(x);
- rect.set_right(static_cast<long>(x+width)-1);
- rect.set_bottom(static_cast<long>(y+height)-1);
-
- parent.invalidate_rectangle(rect+old);
- m.unlock();
- }
-
- virtual void show (
- )
- {
- m.lock();
- hidden = false;
- parent.invalidate_rectangle(rect);
- m.unlock();
- }
-
- virtual void hide (
- )
- {
- m.lock();
- hidden = true;
- parent.invalidate_rectangle(rect);
- m.unlock();
- }
-
- base_window& parent_window (
- ) { return parent; }
-
- const base_window& parent_window (
- ) const { return parent; }
-
- virtual int next_free_user_event_number (
- )const { return 0; }
-
- protected:
- rectangle rect;
- const rmutex& m;
- drawable_window& parent;
- bool hidden;
- bool enabled;
- const long& lastx;
- const long& lasty;
- std::shared_ptr<font> mfont;
-
-
- void enable_events (
- );
-
- bool events_are_enabled (
- ) const { auto_mutex M(m); return enabled_events; }
-
- void disable_events (
- );
-
- private:
-
- long z_order_value;
- const unsigned long events;
- bool enabled_events;
- unsigned long event_id;
-
-
- // restricted functions
- drawable(drawable&); // copy constructor
- drawable& operator=(drawable&); // assignment operator
-
-
- protected:
-
- virtual void draw (
- const canvas& c
- ) const=0;
-
- virtual void on_user_event (
- int
- ){}
-
- virtual void on_window_resized(
- ){}
-
- virtual void on_window_moved(
- ){}
-
- virtual void on_mouse_down (
- unsigned long ,
- unsigned long ,
- long ,
- long ,
- bool
- ){}
-
- virtual void on_mouse_up (
- unsigned long ,
- unsigned long ,
- long ,
- long
- ){}
-
- virtual void on_mouse_move (
- unsigned long ,
- long ,
- long
- ){}
-
- virtual void on_mouse_leave (
- ){}
-
- virtual void on_mouse_enter (
- ){}
-
- virtual void on_wheel_up (
- unsigned long
- ){}
-
- virtual void on_wheel_down (
- unsigned long
- ){}
-
- virtual void on_focus_gained (
- ){}
-
- virtual void on_focus_lost (
- ){}
-
- virtual void on_keydown (
- unsigned long ,
- bool ,
- unsigned long
- ){}
-
- virtual void on_string_put (
- const std::wstring&
- ){}
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "drawable.cpp"
-#endif
-
-#endif // DLIB_DRAWABLe_
-
diff --git a/ml/dlib/dlib/gui_widgets/drawable_abstract.h b/ml/dlib/dlib/gui_widgets/drawable_abstract.h
deleted file mode 100644
index 8f741d8bb..000000000
--- a/ml/dlib/dlib/gui_widgets/drawable_abstract.h
+++ /dev/null
@@ -1,717 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-
-#undef DLIB_DRAWABLe_ABSTRACT_
-#ifdef DLIB_DRAWABLe_ABSTRACT_
-
-#include "../gui_core.h"
-#include "fonts_abstract.h"
-#include "canvas_drawing_abstract.h"
-
-namespace dlib
-{
-
- /*!
- GENERAL REMARKS
- This file defines the drawable interface class and the drawable_window which
- is just a window that is capable of displaying drawable objects (i.e. objects
- that implement the drawable interface).
-
- The drawable interface is a simple framework for creating more complex
- graphical widgets. It provides a default set of functionality and a
- set of events which a gui widget may use.
-
- THREAD SAFETY
- All objects and functions defined in this file are thread safe. You may
- call them from any thread without serializing access to them.
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class drawable_window
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class drawable_window : public base_window
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a window on the desktop that is capable of
- containing drawable objects.
-
- INITIAL STATE
- The initial state of the drawable_window is to be hidden. This means
- you need to call show() to make it appear.
-
- EVENTS
- The drawable_window object uses all the events provided by base_window
- except for the on_window_close() event. This means that if you
- define handlers for these events yourself you will have to call
- the drawable_window's version of them so that the drawable_window
- can continue to process and forward these events to its drawable
- objects.
- !*/
- public:
-
- drawable_window (
- bool resizable = true,
- bool undecorated = false
- );
- /*!
- requires
- - if (undecorated == true) then
- - resizable == false
- ensures
- - #*this has been properly initialized
- - #background_color() == rgb_pixel(212,208,200)
- - if (resizable == true) then
- - this window will be resizable by the user
- - else
- - this window will not be resizable by the user
- - if (undecorated == true) then
- - this window will not have any graphical elements outside
- of its drawable area or appear in the system task bar.
- (e.g. a popup menu)
- throws
- - std::bad_alloc
- - dlib::thread_error
- - dlib::gui_error
- This exception is thrown if there is an error while
- creating this window.
- !*/
-
- virtual ~drawable_window(
- )=0;
- /*!
- ensures
- - if (this window has not already been closed) then
- - closes the window
- - does NOT trigger the on_window_close() event
- - all resources associated with *this have been released
- !*/
-
- void set_background_color (
- unsigned long red,
- unsigned long green,
- unsigned long blue
- );
- /*!
- ensures
- - #background_color().red == red
- - #background_color().green == green
- - #background_color().blue == blue
- !*/
-
- rgb_pixel background_color (
- ) const;
- /*!
- ensures
- - returns the background color this window paints its canvas
- with before it passes it onto its drawable widgets
- !*/
-
- private:
- // restricted functions
- drawable_window(drawable_window&); // copy constructor
- drawable_window& operator=(drawable_window&); // assignment operator
-
- friend class drawable;
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class drawable
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- enum
- {
- MOUSE_MOVE = 1,
- MOUSE_CLICK = 2,
- MOUSE_WHEEL = 4,
- WINDOW_RESIZED = 8,
- KEYBOARD_EVENTS = 16,
- FOCUS_EVENTS = 32,
- WINDOW_MOVED = 64,
- STRING_PUT = 128
- };
-
- class drawable
- {
- /*!
- INITIAL VALUE
- top() == 0
- left() == 0
- right() == -1
- bottom() == -1
- get_rect().is_empty() == true
- is_hidden() == false
- is_enabled() == true
- z_order() == 0
- main_font() == default_font::get_font()
-
- WHAT THIS OBJECT REPRESENTS
- This is an interface that all drawable widgets implement. It
- provides a standard method (draw()) to draw a widget onto a canvas
- and many other convenient functions for drawable objects.
-
- EVENT FORWARDING
- All the events that come to a drawable object are forwarded from its
- parent window. Additionally, there is no filtering. This means that
- if a drawable registers to receive a certain kind of event then whenever
- its parent window receives that event the drawable object will get a
- forwarded copy of it as well even if the event occurred outside the
- drawable's rectangle.
-
- The only events that have anything in the way of filtering are the
- draw() and on_user_event() events. draw() is only called on a drawable
- object when that object is not hidden. on_user_event() is only called
- for drawables that the on_user_event()'s first argument specifically
- references. All other events are not filtered at all though.
-
- Z ORDER
- Z order defines the order in which drawable objects are drawn. The
- lower numbered drawables are drawn first and then the higher numbered
- ones. So a drawable with a z order of 0 is drawn before one with a
- z order of 1 and so on.
- !*/
-
- public:
-
- friend class drawable_window;
-
- drawable (
- drawable_window& w,
- unsigned long events = 0
- ) :
- m(w.wm),
- parent(w),
- hidden(false),
- enabled(true)
- {}
- /*!
- ensures
- - #*this is properly initialized
- - #parent_window() == w
- - #*this will not receive any events or draw() requests until
- enable_events() is called
- - once events_are_enabled() == true this drawable will receive
- the on_user_event() event. (i.e. you always get this event, you don't
- have to enable it by setting something in the events bitset).
- - if (events & MOUSE_MOVE) then
- - once events_are_enabled() == true this drawable will receive
- the following events related to mouse movement: on_mouse_move,
- on_mouse_leave, and on_mouse_enter.
- - if (events & MOUSE_CLICK) then
- - once events_are_enabled() == true this drawable will receive
- the following events related to mouse clicks: on_mouse_down and
- on_mouse_up.
- - if (events & MOUSE_WHEEL) then
- - once events_are_enabled() == true this drawable will receive
- the following events related to mouse wheel scrolling:
- on_wheel_up and on_wheel_down.
- - if (events & WINDOW_RESIZED) then
- - once events_are_enabled() == true this drawable will receive
- the following event related to its parent window resizing:
- on_window_resized.
- - if (events & KEYBOARD_EVENTS) then
- - once events_are_enabled() == true this drawable will receive
- the following keyboard event: on_keydown.
- - if (events & FOCUS_EVENTS) then
- - once events_are_enabled() == true this drawable will receive
- the following focus events: on_focus_gained and on_focus_lost.
- - if (events & WINDOW_MOVED) then
- - once events_are_enabled() == true this drawable will receive
- the following event related to its parent window moving:
- on_window_moved.
- - if (events & STRING_PUT) then
- - once events_are_enabled() == true this drawable will receive
- the following event related to wide character string input:
- on_string_put.
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~drawable (
- );
- /*!
- requires
- - events_are_enabled() == false
- ensures
- - any resources associated with *this have been released
- - *this has been removed from its containing window parent_window() and
- its parent window will no longer try to dispatch events to it.
- Note that this does not trigger a redraw of the parent window. If you
- want to do that you must do it yourself.
- !*/
-
- long z_order (
- ) const;
- /*!
- ensures
- - returns the z order for this drawable.
- !*/
-
- virtual void set_z_order (
- long order
- );
- /*!
- ensures
- - #z_order() == order
- - if (events_are_enabled() == true) then
- - parent_window() is updated to reflect the new state of #*this
- throws
- - std::bad_alloc
- !*/
-
- const rectangle get_rect (
- ) const;
- /*!
- ensures
- - returns the rectangle that defines the area and position of this
- drawable inside its containing window parent_window().
- !*/
-
- long bottom (
- ) const;
- /*!
- ensures
- - returns get_rect().bottom()
- !*/
-
- long top (
- ) const;
- /*!
- ensures
- - returns get_rect().top()
- !*/
-
- long left (
- ) const;
- /*!
- ensures
- - returns get_rect().left()
- !*/
-
- long right (
- ) const;
- /*!
- ensures
- - returns get_rect().right()
- !*/
-
- unsigned long width (
- ) const;
- /*!
- ensures
- - returns get_rect().width()
- !*/
-
- unsigned long height (
- ) const;
- /*!
- ensures
- - returns get_rect().height()
- !*/
-
- virtual void set_pos (
- long x,
- long y
- );
- /*!
- ensures
- - #top() == y
- - #left() == x
- - #width() == width()
- - #height() == height()
- - if (events_are_enabled() == true) then
- - parent_window() is updated to reflect the new state of #*this
- - i.e. This just sets the upper left corner of this drawable to the
- location (x,y)
- !*/
-
- bool is_enabled (
- ) const;
- /*!
- ensures
- - returns true if this object is enabled and false otherwise.
- (it is up to derived classes to define exactly what it means to be
- "enabled")
- !*/
-
- virtual void enable (
- );
- /*!
- ensures
- - #is_enabled() == true
- - if (events_are_enabled() == true) then
- - parent_window() is updated to reflect the new state of #*this
- !*/
-
- virtual void disable (
- );
- /*!
- ensures
- - #is_enabled() == false
- - if (events_are_enabled() == true) then
- - parent_window() is updated to reflect the new state of #*this
- !*/
-
- virtual void set_main_font (
- const shared_ptr_thread_safe<font>& f
- );
- /*!
- ensures
- - #main_font() == f
- - if (events_are_enabled() == true) then
- - parent_window() is updated to reflect the new state of #*this
- !*/
-
- const shared_ptr_thread_safe<font> main_font (
- ) const;
- /*!
- ensures
- - returns the current main font being used by this widget
- !*/
-
- bool is_hidden (
- ) const;
- /*!
- ensures
- - returns true if this object is NOT currently displayed on parent_window()
- and false otherwise.
- !*/
-
- virtual void show (
- );
- /*!
- ensures
- - #is_hidden() == false
- - if (events_are_enabled() == true) then
- - parent_window() is updated to reflect the new state of #*this
- !*/
-
- virtual void hide (
- );
- /*!
- ensures
- - #is_hidden() == true
- - if (events_are_enabled() == true) then
- - parent_window() is updated to reflect the new state of #*this
- !*/
-
- drawable_window& parent_window (
- );
- /*!
- ensures
- - returns a reference to the drawable_window that this drawable is
- being drawn on and receiving events from.
- !*/
-
- const drawable_window& parent_window (
- ) const;
- /*!
- ensures
- - returns a const reference to the drawable_window that this drawable
- is being drawn on and receiving events from.
- !*/
-
- virtual int next_free_user_event_number (
- )const { return 0; }
- /*!
- ensures
- - returns the smallest number, i, that is the next user event number you
- can use in calls to parent.trigger_user_event((void*)this,i).
- - This function exists because of the following scenario. Suppose
- you make a class called derived1 that inherits from drawable and
- in derived1 you use a user event to do something. Then suppose
- you inherit from derived1 to make derived2. Now in derived2 you
- may want to use a user event to do something as well. How are you
- to know which user event numbers are in use already? This function
- solves that problem. You would define derived1::next_free_user_event_number()
- so that it returned a number bigger than any user event numbers used by
- derived1 or its ancestors. Then derived2 could just call
- derived1::next_free_user_event_number() to find out what numbers it could use.
- !*/
-
- protected:
- /*!A drawable_protected_variables
-
- These protected members are provided because they are needed to
- implement drawable widgets.
- !*/
-
- // This is the rectangle that is returned by get_rect()
- rectangle rect;
-
- // This is the mutex used to serialize access to this class.
- const rmutex& m;
-
- // This is the parent window of this drawable
- drawable_window& parent;
-
- // This is the bool returned by is_hidden()
- bool hidden;
-
- // This is the bool returned by is_enabled()
- bool enabled;
-
- // This is the font pointer returned by main_font()
- shared_ptr_thread_safe<font> mfont;
-
- // This is the x coordinate that we last saw the mouse at or -1 if the mouse
- // is outside the parent window.
- const long& lastx;
-
- // This is the y coordinate that we last saw the mouse at or -1 if the mouse
- // is outside the parent window.
- const long& lasty;
-
-
- void enable_events (
- );
- /*!
- ensures
- - #events_are_enabled() == true
- !*/
-
- void disable_events (
- );
- /*!
- ensures
- - #events_are_enabled() == false
- !*/
-
- bool events_are_enabled (
- ) const;
- /*!
- ensures
- - returns true if this object is receiving events and draw()
- requests from its parent window.
- - returns false otherwise
- !*/
-
- // ---------------- EVENT HANDLERS ------------------
-
- virtual void on_user_event (
- int i
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - is called whenever the parent window receives an on_user_event(p,i) event
- where p == this. (i.e. this is just a redirect of on_user_event for
- cases where the first argument of on_user_event is equal to the
- this pointer).
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_window_resized(
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_window_resized() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_window_moved(
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_window_moved() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_mouse_down() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_mouse_up() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_mouse_move (
- unsigned long state,
- long x,
- long y
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - x == lastx
- - y == lasty
- - this is just the base_window::on_mouse_move() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_mouse_leave (
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_mouse_leave() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_mouse_enter (
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_mouse_enter() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_wheel_up (
- unsigned long state
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_wheel_up() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_wheel_down (
- unsigned long state
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_wheel_down() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_focus_gained (
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_focus_gained() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_focus_lost (
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_focus_lost() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_keydown() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void on_string_put (
- const std::wstring &str
- ){}
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - this is just the base_window::on_put_string() event forwarded to
- this object. See the gui_core specs for the details about this event.
- ensures
- - does not change the state of mutex m.
- !*/
-
- virtual void draw (
- const canvas& c
- ) const=0;
- /*!
- requires
- - events_are_enabled() == true
- - mutex m is locked
- - is_hidden() == false
- - is called by parent_window() when it needs to repaint itself.
- - c == the canvas object for the area of parent_window() that needs
- to be repainted.
- ensures
- - does not change the state of mutex m.
- - draws the area of *this that intersects with the canvas onto
- the canvas object c.
- !*/
-
- private:
-
- // restricted functions
- drawable(drawable&); // copy constructor
- drawable& operator=(drawable&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_DRAWABLe_ABSTRACT_
-
diff --git a/ml/dlib/dlib/gui_widgets/fonts.cpp b/ml/dlib/dlib/gui_widgets/fonts.cpp
deleted file mode 100644
index dfbf9f720..000000000
--- a/ml/dlib/dlib/gui_widgets/fonts.cpp
+++ /dev/null
@@ -1,673 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), and Nils Labugt, Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_FONTs_CPP_
-#define DLIB_FONTs_CPP_
-
-#include "fonts.h"
-
-#include <fstream>
-#include <memory>
-#include <sstream>
-
-#include "../serialize.h"
-#include "../base64.h"
-#include "../compress_stream.h"
-#include "../tokenizer.h"
-#include "nativefont.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- const std::string get_decoded_string_with_default_font_data()
- {
- dlib::base64::kernel_1a base64_coder;
- dlib::compress_stream::kernel_1ea compressor;
- std::ostringstream sout;
- std::istringstream sin;
-
- /*
- SOURCE BDF FILE (helvR12.bdf) COMMENTS
- COMMENT $XConsortium: helvR12.bdf,v 1.15 95/01/26 18:02:58 gildea Exp $
- COMMENT $Id: helvR12.bdf,v 1.26 2004-11-28 20:08:46+00 mgk25 Rel $
- COMMENT
- COMMENT +
- COMMENT Copyright 1984-1989, 1994 Adobe Systems Incorporated.
- COMMENT Copyright 1988, 1994 Digital Equipment Corporation.
- COMMENT
- COMMENT Adobe is a trademark of Adobe Systems Incorporated which may be
- COMMENT registered in certain jurisdictions.
- COMMENT Permission to use these trademarks is hereby granted only in
- COMMENT association with the images described in this file.
- COMMENT
- COMMENT Permission to use, copy, modify, distribute and sell this software
- COMMENT and its documentation for any purpose and without fee is hereby
- COMMENT granted, provided that the above copyright notices appear in all
- COMMENT copies and that both those copyright notices and this permission
- COMMENT notice appear in supporting documentation, and that the names of
- COMMENT Adobe Systems and Digital Equipment Corporation not be used in
- COMMENT advertising or publicity pertaining to distribution of the software
- COMMENT without specific, written prior permission. Adobe Systems and
- COMMENT Digital Equipment Corporation make no representations about the
- COMMENT suitability of this software for any purpose. It is provided "as
- COMMENT is" without express or implied warranty.
- COMMENT -
- */
-
- // The base64 encoded data we want to decode and return.
- sout << "AXF+zOQzCgGitrKiOCGEL4hlIv1ZenWJyjMQ4rJ6f/oPMeHqsZn+8XnpehwFQTz3dtUGlZRAUoOa";
- sout << "uVo8UiplcFxuK69A+94rpMCMAyEeeOwZ/tRzkX4eKuU3L4xtsJDknMiYUNKaMrYimb1QJ0E+SRqQ";
- sout << "wATrMTecYNZvJJm02WibiwE4cJ5scvkHNl4KJT5QfdwRdGopTyUVdZvRvtbTLLjsJP0fQEQLqemf";
- sout << "qPE4kDD79ehrBIwLO1Y6TzxtrrIoQR57zlwTUyLenqRtSN3VLtjWYd82cehRIlTLtuxBg2s+zZVq";
- sout << "jNlNnYTSM+Swy06qnQgg+Dt0lhtlB9shR1OAlcfCtTW6HKoBk/FGeDmjTGW4bNCGv7RjgM6TlLDg";
- sout << "ZYSSA6ZCCAKBgE++U32gLHCCiVkPTkkp9P6ioR+e3SSKRNm9p5MHf+ZQ3LJkW8KFJ/K9gKT1yvyv";
- sout << "F99pAvOOq16tHRFvzBs+xZj/mUpH0lGIS7kLWr9oP2KuccVrz25aJn3kDruwTYoD+CYlOqtPO0Mv";
- sout << "dEI0LUR0Ykp1M2rWo76fJ/fpzHjV7737hjkNPJ13nO72RMDr4R5V3uG7Dw7Ng+vGX3WgJZ4wh1JX";
- sout << "pl2VMqC5JXccctzvnQvnuvBvRm7THgwQUgMKKT3WK6afUUVlJy8DHKuU4k1ibfVMxAmrwKdTUX2w";
- sout << "cje3A05Qji3aop65qEdwgI5O17HIVoRQOG/na+XRMowOfUvI4H8Z4+JGACfRrQctgYDAM9eJzm8i";
- sout << "PibyutmJfZBGg0a3oC75S5R9lTxEjPocnEyJRYNnmVnVAmKKbTbTsznuaD+D1XhPdr2t3A4bRTsp";
- sout << "toKKtlFnd9YGwLWwONDwLnoQ/IXwyF7txrRHNSVToh772U0Aih/yn5vnmcMF750eiMzRAgXu5sbR";
- sout << "VXEOVCiLgVevN5umkvjZt1eGTSSzDMrIvnv4nyOfaFsD+I76wQfgLqd71rheozGtjNc0AOTx4Ggc";
- sout << "eUSFHTDAVfTExBzckurtyuIAqF986a0JLHCtsDpBa2wWNuiQYOH3/LX1zkdU2hdamhBW774bpEwr";
- sout << "dguMxxOeDGOBgIlM5gxXGYXSf5IN3fUAEPfOPRxB7T+tpjFnWd7cg+JMabci3zhJ9ANaYT7HGeTX";
- sout << "bulKnGHjYrR1BxdK3YeliogQRU4ytmxlyL5zlNFU/759mA8XSfIPMEZn9Vxkb00q1htF7REiDcr3";
- sout << "kW1rtPAc7VQNEhT54vK/YF6rMvjO7kBZ/vLYo7E8e8hDKEnY8ucrC3KGmeo31Gei74BBcEbvJBd3";
- sout << "/YAaIKgXWwU2wSUw9wLq2RwGwyguvKBx0J/gn27tjcVAHorRBwxzPpk8r+YPyN+SifSzEL7LEy1G";
- sout << "lPHxmXTrcqnH9qraeAqXJUJvU8SJJpf/tmsAE+XSKD/kpVBnT5qXsJ1SRFS7MtfPjE1j/NYbaQBI";
- sout << "bOrh81zaYCEJR0IKHWCIsu/MC3zKXfkxFgQ9XpYAuWjSSK64YpgkxSMe8VG8yYvigOw2ODg/z4FU";
- sout << "+HpnEKF/M/mKfLKK1i/8BV7xcYVHrhEww1QznoFklJs/pEg3Kd5PE1lRii6hvTn6McVAkw+YbH9q";
- sout << "/sg4gFIAvai64hMcZ1oIZYppj3ZN6KMdyhK5s4++ZS/YOV2nNhW73ovivyi2Tjg7lxjJJtsYrLKb";
- sout << "zIN1slOICKYwBq42TFBcFXaZ6rf0Czd09tL+q6A1Ztgr3BNuhCenjhWN5ji0LccGYZo6bLTggRG/";
- sout << "Uz6K3CBBU/byLs79c5qCohrr7rlpDSdbuR+aJgNiWoU6T0i2Tvua6h51LcWEHy5P2n146/Ae2di4";
- sout << "eh20WQvclrsgm1oFTGD0Oe85GKOTA7vvwKmLBc1wwA0foTuxzVgj0TMTFBiYLTLG4ujUyBYy1N6e";
- sout << "H8EKi8H+ZAlqezrjABO3BQr33ewdZL5IeJ4w7gdGUDA6+P+7cODcBW50X9++6YTnKctuEw6aXBpy";
- sout << "GgcMfPE61G8YKBbFGFic3TVvGCLvre1iURv+F+hU4/ee6ILuPnpYnSXX2iCIK/kmkBse8805d4Qe";
- sout << "DG/8rBW9ojvAgc0jX7CatPEMHGkcz+KIZoKMI7XXK4PJpGQUdq6EdIhJC4koXEynjwwXMeC+jJqH";
- sout << "agwrlDNssq/8AA==";
-
-
-
- // Put the data into the istream sin
- sin.str(sout.str());
- sout.str("");
-
- // Decode the base64 text into its compressed binary form
- base64_coder.decode(sin,sout);
- sin.clear();
- sin.str(sout.str());
- sout.str("");
-
- // Decompress the data into its original form
- compressor.decompress(sin,sout);
-
- // Return the decoded and decompressed data
- return sout.str();
- }
-
-
- default_font::
- default_font (
- )
- {
- using namespace std;
- l = new letter[256];
-
- try
- {
- istringstream sin(get_decoded_string_with_default_font_data());
-
- for (int i = 0; i < 256; ++i)
- {
- deserialize(l[i],sin);
- }
-
- }
- catch (...)
- {
- delete [] l;
- throw;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void serialize (
- const letter& item,
- std::ostream& out
- )
- {
- try
- {
- serialize(item.w,out);
- serialize(item.count,out);
-
- for (unsigned long i = 0; i < item.count; ++i)
- {
- serialize(item.points[i].x,out);
- serialize(item.points[i].y,out);
- }
- }
- catch (serialization_error e)
- {
- throw serialization_error(e.info + "\n while serializing object of type letter");
- }
- }
-
- void deserialize (
- letter& item,
- std::istream& in
- )
- {
- try
- {
- if (item.points)
- delete [] item.points;
-
- deserialize(item.w,in);
- deserialize(item.count,in);
-
- if (item.count > 0)
- item.points = new letter::point[item.count];
- else
- item.points = 0;
-
- for (unsigned long i = 0; i < item.count; ++i)
- {
- deserialize(item.points[i].x,in);
- deserialize(item.points[i].y,in);
- }
- }
- catch (serialization_error e)
- {
- item.w = 0;
- item.count = 0;
- item.points = 0;
- throw serialization_error(e.info + "\n while deserializing object of type letter");
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace bdf_font_helpers
- {
- class bdf_parser
- {
- public:
- bdf_parser( std::istream& in ) : in_( in )
- {
- std::string str_tmp;
- int int_tmp;
-
- str_tmp = "STARTFONT"; int_tmp = STARTFONT; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "FONTBOUNDINGBOX";int_tmp = FONTBOUNDINGBOX; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "DWIDTH"; int_tmp = DWIDTH; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "CHARS"; int_tmp = CHARS; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "STARTCHAR"; int_tmp = STARTCHAR; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "ENCODING"; int_tmp = ENCODING; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "BBX"; int_tmp = BBX; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "BITMAP"; int_tmp = BITMAP; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "ENDCHAR"; int_tmp = ENDCHAR; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "ENDFONT"; int_tmp = ENDFONT; keyword_map.add( str_tmp, int_tmp );
- str_tmp = "DEFAULT_CHAR"; int_tmp = DEFAULT_CHAR; keyword_map.add( str_tmp, int_tmp );
-
- tokzr.set_identifier_token( tokzr.uppercase_letters(), tokzr.uppercase_letters() + "_" );
- tokzr.set_stream( in );
-
- }
-
- enum bdf_enums
- {
- NO_KEYWORD = 0,
- STARTFONT = 1,
- FONTBOUNDINGBOX = 2,
- DWIDTH = 4,
- DEFAULT_CHAR = 8,
- CHARS = 16,
- STARTCHAR = 32,
- ENCODING = 64,
- BBX = 128,
- BITMAP = 256,
- ENDCHAR = 512,
- ENDFONT = 1024
-
- };
- struct header_info
- {
- int FBBx, FBBy, Xoff, Yoff;
- int dwx0, dwy0;
- bool has_global_dw;
- long default_char;
- };
- struct char_info
- {
- int dwx0, dwy0;
- int BBw, BBh, BBxoff0x, BByoff0y;
- array2d<char> bitmap;
- bool has_dw;
- };
- bool parse_header( header_info& info )
- {
- if ( required_keyword( STARTFONT ) == false )
- return false; // parse_error: required keyword missing
- info.has_global_dw = false;
- int find = FONTBOUNDINGBOX | DWIDTH | DEFAULT_CHAR;
- int stop = CHARS | STARTCHAR | ENCODING | BBX | BITMAP | ENDCHAR | ENDFONT;
- int res;
- while ( 1 )
- {
- res = find_keywords( find | stop );
- if ( res & FONTBOUNDINGBOX )
- {
- in_ >> info.FBBx >> info.FBBy >> info.Xoff >> info.Yoff;
- if ( in_.fail() )
- return false; // parse_error
- find &= ~FONTBOUNDINGBOX;
- continue;
- }
- if ( res & DWIDTH )
- {
- in_ >> info.dwx0 >> info.dwy0;
- if ( in_.fail() )
- return false; // parse_error
- find &= ~DWIDTH;
- info.has_global_dw = true;
- continue;
- }
- if ( res & DEFAULT_CHAR )
- {
- in_ >> info.default_char;
- if ( in_.fail() )
- return false; // parse_error
- find &= ~DEFAULT_CHAR;
- continue;
- }
- if ( res & NO_KEYWORD )
- return false; // parse_error: unexpected EOF
- break;
- }
- if ( res != CHARS || ( find & FONTBOUNDINGBOX ) )
- return false; // parse_error: required keyword missing or unexpeced keyword
- return true;
- }
- int parse_glyph( char_info& info, unichar& enc )
- {
- info.has_dw = false;
- int e;
- int res;
- while ( 1 )
- {
- res = find_keywords( ENCODING );
- if ( res != ENCODING )
- return 0; // no more glyphs
- in_ >> e;
- if ( in_.fail() )
- return -1; // parse_error
- if ( e >= static_cast<int>(enc) )
- break;
- }
- int find = BBX | DWIDTH;
- int stop = STARTCHAR | ENCODING | BITMAP | ENDCHAR | ENDFONT;
- while ( 1 )
- {
- res = find_keywords( find | stop );
- if ( res & BBX )
- {
- in_ >> info.BBw >> info.BBh >> info.BBxoff0x >> info.BByoff0y;
- if ( in_.fail() )
- return -1; // parse_error
- find &= ~BBX;
- continue;
- }
- if ( res & DWIDTH )
- {
- in_ >> info.dwx0 >> info.dwy0;
- if ( in_.fail() )
- return -1; // parse_error
- find &= ~DWIDTH;
- info.has_dw = true;
- continue;
- }
- if ( res & NO_KEYWORD )
- return -1; // parse_error: unexpected EOF
- break;
- }
- if ( res != BITMAP || ( find != NO_KEYWORD ) )
- return -1; // parse_error: required keyword missing or unexpeced keyword
- unsigned h = info.BBh;
- unsigned w = ( info.BBw + 7 ) / 8 * 2;
- info.bitmap.set_size( h, w );
- for ( unsigned r = 0;r < h;r++ )
- {
- trim();
- std::string str = "";
- extract_hex(str);
- if(str.size() < w)
- return -1; // parse_error
- for ( unsigned c = 0;c < w;c++ )
- info.bitmap[r][c] = str[c];
- }
- if ( in_.fail() )
- return -1; // parse_error
- if ( required_keyword( ENDCHAR ) == false )
- return -1; // parse_error: required keyword missing
- enc = e;
- return 1;
- }
- private:
- map<std::string, int>::kernel_1a_c keyword_map;
- tokenizer::kernel_1a_c tokzr;
- std::istream& in_;
- void extract_hex(std::string& str)
- {
- int type;
- std::string token;
- while ( 1 )
- {
- type = tokzr.peek_type();
- if ( type == tokenizer::kernel_1a_c::IDENTIFIER || type == tokenizer::kernel_1a_c::NUMBER )
- {
- tokzr.get_token( type, token );
- str += token;
- continue;
- }
- break;
- }
- }
- void trim()
- {
- int type;
- std::string token;
- while ( 1 )
- {
- type = tokzr.peek_type();
- if ( type == tokenizer::kernel_1a_c::WHITE_SPACE || type == tokenizer::kernel_1a_c::END_OF_LINE )
- {
- tokzr.get_token( type, token );
- continue;
- }
- break;
- }
- }
- bool required_keyword( int kw )
- {
- int type;
- std::string token;
- while ( 1 )
- {
- tokzr.get_token( type, token );
- if ( type == tokenizer::kernel_1a_c::WHITE_SPACE || type == tokenizer::kernel_1a_c::END_OF_LINE )
- continue;
- if ( type != tokenizer::kernel_1a_c::IDENTIFIER || keyword_map.is_in_domain( token ) == false || ( keyword_map[token] & kw ) == 0 )
- return false;
- break;
- }
- return true;
- }
- int find_keywords( int find )
- {
- int type;
- std::string token;
- while ( 1 )
- {
- tokzr.get_token( type, token );
- if ( type == tokenizer::kernel_1a_c::END_OF_FILE )
- return NO_KEYWORD;
- if ( type == tokenizer::kernel_1a_c::IDENTIFIER && keyword_map.is_in_domain( token ) == true )
- {
- int kw = keyword_map[token];
- if ( kw & find )
- return kw;
- }
- }
- return true;
- }
-
- };
-
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// bdf_font functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- bdf_font::bdf_font(
- long default_char_
- ) :
- default_char(0),
- is_initialized( false ),
- right_overflow_( 0 ),
- has_global_width( false ),
- specified_default_char( default_char_ )
- {
- // make sure gl contains at least one letter
- gl.resize(1);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void bdf_font::adjust_metrics(
- )
- {
- if ( is_initialized == false )
- return;
- // set starting values for fbb
- if ( gl[default_char].num_of_points() > 0 )
- {
- letter& g = gl[default_char];
- fbb.set_top( g[0].y );
- fbb.set_bottom( g[0].y );
- fbb.set_left( g[0].x );
- fbb.set_right( g[0].x );
- }
- else
- {
- // ok, the default char was a space
- // let's just choose some safe arbitrary values then...
- fbb.set_top( 10000 );
- fbb.set_bottom( -10000 );
- fbb.set_left( 10000 );
- fbb.set_right( -10000 );
- }
- right_overflow_ = 0;
- for ( unichar n = 0; n < gl.size(); n++ )
- {
- letter& g = gl[n];
- unsigned short nr_pts = g.num_of_points();
- for ( unsigned short k = 0;k < nr_pts;k++ )
- {
- fbb.set_top( std::min( fbb.top(), (long)g[k].y ) );
- fbb.set_left( std::min( fbb.left(), (long)g[k].x ) );
- fbb.set_bottom( std::max( fbb.bottom(), (long)g[k].y ) );
- fbb.set_right( std::max( fbb.right(), (long)g[k].x ) );
- right_overflow_ = std::max( right_overflow_, (unsigned long)(g[k].x - g.width()) ); // superfluous?
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- long bdf_font::
- read_bdf_file(
- std::istream& in,
- unichar max_enc,
- unichar min_enc
- )
- {
- using namespace bdf_font_helpers;
-
- bdf_parser parser( in );
- bdf_parser::header_info hinfo;
- bdf_parser::char_info cinfo;
-
- gl.resize(max_enc+1);
- hinfo.default_char = - 1;
- if ( is_initialized == false || static_cast<std::streamoff>(in.tellg()) == std::ios::beg )
- {
- if ( parser.parse_header( hinfo ) == false )
- return 0; // parse_error: invalid or missing header
- }
- else
- {
- // not start of file, so use values from previous read.
- hinfo.has_global_dw = has_global_width;
- hinfo.dwx0 = global_width;
- }
- int res;
- unichar nr_letters_added = 0;
- unsigned width;
- for ( unichar n = min_enc; n <= max_enc; n++ )
- {
- if ( in.eof() )
- break;
- long pos = in.tellg();
- res = parser.parse_glyph( cinfo, n );
- if ( res < 0 )
- return 0; // parse_error
- if ( res == 0 )
- continue;
- if ( n > max_enc )
- {
- in.seekg( pos );
- break;
- }
-
- if ( cinfo.has_dw == false )
- {
- if ( hinfo.has_global_dw == false )
- return 0; // neither width info for the glyph, nor for the font as a whole (monospace).
- width = hinfo.dwx0;
- }
- else
- width = cinfo.dwx0;
-
-
- if ( bitmap_to_letter( cinfo.bitmap, n, width, cinfo.BBxoff0x, cinfo.BByoff0y ) == false )
- return 0;
- nr_letters_added++;
-
- if ( is_initialized == false )
- {
- // Bonding rectangle for the font.
- fbb.set_top( -( hinfo.Yoff + hinfo.FBBy - 1 ) );
- fbb.set_bottom( -hinfo.Yoff );
- fbb.set_left( hinfo.Xoff );
- fbb.set_right( hinfo.Xoff + hinfo.FBBx - 1 );
- // We need to compute this after all the glyphs are loaded.
- right_overflow_ = 0;
- // set this to something valid now, just in case.
- default_char = n;
- // Save any global width in case we later read from the same file.
- has_global_width = hinfo.has_global_dw;
- if ( has_global_width )
- global_width = hinfo.dwx0;
- // dont override value specified in the constructor with value specified in the file
- if ( specified_default_char < 0 && hinfo.default_char >= 0 )
- specified_default_char = hinfo.default_char;
-
- is_initialized = true;
- }
- }
- if ( is_initialized == false )
- return 0; // Not a single glyph was found within the specified range.
-
- if ( specified_default_char >= 0 )
- default_char = specified_default_char;
- // no default char specified, try find something sane.
- else
- default_char = 0;
-
- return nr_letters_added;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool bdf_font::
- bitmap_to_letter(
- array2d<char>& bitmap,
- unichar enc,
- unsigned long width,
- int x_offset,
- int y_offset
- )
- {
- unsigned nr_points = 0;
- bitmap.reset();
- while ( bitmap.move_next() )
- {
- unsigned char ch = bitmap.element();
- if ( ch > '9' )
- ch -= 'A' - '9' - 1;
- ch -= '0';
- if ( ch > 0xF )
- return false; // parse error: invalid hex digit
- bitmap.element() = ch;
- if ( ch & 8 )
- nr_points++;
- if ( ch & 4 )
- nr_points++;
- if ( ch & 2 )
- nr_points++;
- if ( ch & 1 )
- nr_points++;
- }
-
- letter( width, nr_points ).swap(gl[enc]);
-
- unsigned index = 0;
- for ( int r = 0;r < bitmap.nr();r++ )
- {
- for ( int c = 0;c < bitmap.nc();c++ )
- {
- int x = x_offset + c * 4;
- int y = -( y_offset + bitmap.nr() - r - 1 );
- char ch = bitmap[r][c];
- letter& glyph = gl[enc];
- if ( ch & 8 )
- {
- glyph[index] = letter::point( x, y );
- right_overflow_ = std::max( right_overflow_, x - width );
- index++;
- }
- if ( ch & 4 )
- {
- glyph[index] = letter::point( x + 1, y );
- right_overflow_ = std::max( right_overflow_, x + 1 - width );
- index++;
- }
- if ( ch & 2 )
- {
- glyph[index] = letter::point( x + 2, y );
- right_overflow_ = std::max( right_overflow_, x + 2 - width );
- index++;
- }
- if ( ch & 1 )
- {
- glyph[index] = letter::point( x + 3, y );
- right_overflow_ = std::max( right_overflow_, x + 3 - width );
- index++;
- }
- }
- }
- return true;
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::shared_ptr<font> get_native_font (
- )
- {
- return nativefont::native_font::get_font();
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_FONTs_CPP_
-
diff --git a/ml/dlib/dlib/gui_widgets/fonts.h b/ml/dlib/dlib/gui_widgets/fonts.h
deleted file mode 100644
index 5d3181aaa..000000000
--- a/ml/dlib/dlib/gui_widgets/fonts.h
+++ /dev/null
@@ -1,628 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), and Nils Labugt, Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-
-#ifndef DLIB_FONTs_
-#define DLIB_FONTs_
-
-#include <memory>
-#include <string>
-
-#include "fonts_abstract.h"
-#include "../gui_core.h"
-#include "../algs.h"
-#include "../serialize.h"
-#include "../unicode.h"
-#include "../array.h"
-#include "../array2d.h"
-#include "../threads.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class letter
- {
- /*!
- INITIAL VALUE
- - defined by constructor
-
- CONVENTION
- - if (points != 0) then
- - points == an array of count point structs
- - w == width()
- - count == num_of_points()
- !*/
- public:
- struct point
- {
- point (){}
-
- point (
- signed char x_,
- signed char y_
- ) :
- x(x_),
- y(y_)
- {}
-
- signed char x;
- signed char y;
- };
-
- letter (
- ) :
- points(0),
- w(0),
- count(0)
- {}
-
- letter (
- unsigned short width_,
- unsigned short point_count
- ) :
- points(new point[point_count]),
- w(width_),
- count(point_count)
- {}
-
- ~letter(
- )
- {
- if (points)
- delete [] points;
- }
-
- unsigned short width (
- ) const { return w; }
-
- unsigned short num_of_points (
- ) const { return count;}
-
- point& operator[] (
- unsigned short i
- )
- {
- DLIB_ASSERT (i < num_of_points(),
- "\tvoid letter::operator[]()"
- << "\n\ti: " << i
- << "\n\tnum_of_points(): " << num_of_points() );
- return points[i];
- }
-
- const point& operator[] (
- unsigned short i
- ) const
- {
- DLIB_ASSERT (i < num_of_points(),
- "\tvoid letter::operator[]()"
- << "\n\ti: " << i
- << "\n\tnum_of_points(): " << num_of_points() );
- return points[i];
- }
-
- friend void serialize (
- const letter& item,
- std::ostream& out
- );
-
- friend void deserialize (
- letter& item,
- std::istream& in
- );
-
- void swap (
- letter& item
- )
- {
- exchange(points, item.points);
- exchange(w, item.w);
- exchange(count, item.count);
- }
-
- private:
- // restricted functions
- letter(letter&); // copy constructor
- letter& operator=(letter&); // assignment operator
-
- point* points;
- unsigned short w;
- unsigned short count;
- };
-
- inline void swap (
- letter& a,
- letter& b
- ) { a.swap(b); }
-
-// ----------------------------------------------------------------------------------------
-
- class font
- {
- public:
- virtual ~font() {}
-
- virtual bool has_character (
- unichar ch
- )const=0;
- bool has_character(char ch) const { return this->has_character(zero_extend_cast<unichar>(ch)); }
- bool has_character(wchar_t ch) const { return this->has_character(zero_extend_cast<unichar>(ch)); }
-
- const letter& operator[] (char ch) const { return (*this)[zero_extend_cast<unichar>(ch)]; };
- const letter& operator[] (wchar_t ch)const { return (*this)[zero_extend_cast<unichar>(ch)]; };
-
- virtual const letter& operator[] (
- unichar ch
- )const=0;
-
- virtual unsigned long height (
- ) const = 0;
-
- virtual unsigned long ascender (
- ) const = 0;
-
- virtual unsigned long left_overflow (
- ) const = 0;
-
- virtual unsigned long right_overflow (
- ) const = 0;
-
- // ------------------------------------------------------------------------------------
-
- template <typename T, typename traits, typename alloc>
- void compute_size (
- const std::basic_string<T,traits,alloc>& str,
- unsigned long& width,
- unsigned long& height,
- typename std::basic_string<T,traits,alloc>::size_type first = 0,
- typename std::basic_string<T,traits,alloc>::size_type last = (std::basic_string<T,traits,alloc>::npos)
- ) const
- {
- typedef std::basic_string<T,traits,alloc> string;
- DLIB_ASSERT ( (last == string::npos) || (first <= last && last < str.size()) ,
- "\tvoid font::compute_size()"
- << "\n\tlast == string::npos: " << ((last == string::npos)?"true":"false")
- << "\n\tfirst: " << (unsigned long)first
- << "\n\tlast: " << (unsigned long)last
- << "\n\tstr.size(): " << (unsigned long)str.size() );
-
- unsigned long line_width = 0;
- unsigned long newlines = 0;
- width = 0;
- height = 0;
-
- if (str.size())
- {
- if (last == string::npos)
- last = str.size()-1;
- const font& f = *this;
-
- for (typename string::size_type i = first; i <= last; ++i)
- {
- // ignore '\r' characters
- if (str[i] == '\r')
- continue;
-
- if (str[i] == '\n')
- {
- ++newlines;
- width = std::max(width,line_width);
- line_width = 0;
- }
- else
- {
- if (is_combining_char(str[i]) == false)
- line_width += f[str[i]].width();
- }
- }
- width = std::max(width,line_width);
-
- height = (newlines+1)*f.height();
- width += f.left_overflow() + f.right_overflow();
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <typename T, typename traits, typename alloc, typename pixel_type>
- void draw_string (
- const canvas& c,
- const rectangle& rect,
- const std::basic_string<T,traits,alloc>& str,
- const pixel_type& color,
- typename std::basic_string<T,traits,alloc>::size_type first = 0,
- typename std::basic_string<T,traits,alloc>::size_type last = (std::basic_string<T,traits,alloc>::npos),
- const rectangle area_ = rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max())
- ) const
- {
- typedef std::basic_string<T,traits,alloc> string;
- DLIB_ASSERT ( (last == string::npos) || (first <= last && last < str.size()) ,
- "\tvoid font::draw_string()"
- << "\n\tlast == string::npos: " << ((last == string::npos)?"true":"false")
- << "\n\tfirst: " << (unsigned long)first
- << "\n\tlast: " << (unsigned long)last
- << "\n\tstr.size(): " << (unsigned long)str.size() );
-
- rectangle area = rect.intersect(c).intersect(area_);
- if (area.is_empty() || str.size() == 0)
- return;
-
- if (last == string::npos)
- last = str.size()-1;
-
- const font& f = *this;
-
- long y_offset = rect.top() + f.ascender() - 1;
-
- long pos = rect.left()+f.left_overflow();
- for (typename string::size_type i = first; i <= last; ++i)
- {
- // ignore the '\r' character
- if (str[i] == '\r')
- continue;
-
- // A combining character should be applied to the previous character, and we
- // therefore make one step back. If a combining comes right after a newline,
- // then there must be some kind of error in the string, and we don't combine.
- if(is_combining_char(str[i]) &&
- pos > rect.left() + static_cast<long>(f.left_overflow()))
- {
- pos -= f[str[i]].width();
- }
-
- if (str[i] == '\n')
- {
- y_offset += f.height();
- pos = rect.left()+f.left_overflow();
- continue;
- }
-
- // only look at letters in the intersection area
- if (area.bottom() + static_cast<long>(f.height()) < y_offset)
- {
- // the string is now below our rectangle so we are done
- break;
- }
- else if (area.left() > pos - static_cast<long>(f.left_overflow()) &&
- pos + static_cast<long>(f[str[i]].width() + f.right_overflow()) < area.left() )
- {
- pos += f[str[i]].width();
- continue;
- }
- else if (area.right() + static_cast<long>(f.right_overflow()) < pos)
- {
- // keep looking because there might be a '\n' in the string that
- // will wrap us around and put us back into our rectangle.
- continue;
- }
-
- // at this point in the loop we know that f[str[i]] overlaps
- // horizontally with the intersection rectangle area.
-
- const letter& l = f[str[i]];
- for (unsigned short i = 0; i < l.num_of_points(); ++i)
- {
- const long x = l[i].x + pos;
- const long y = l[i].y + y_offset;
- // draw each pixel of the letter if it is inside the intersection
- // rectangle
- if (area.contains(x,y))
- {
- assign_pixel(c[y-c.top()][x-c.left()], color);
- }
- }
-
- pos += l.width();
- }
- }
- template <typename T, typename traits, typename alloc>
- void draw_string (
- const canvas& c,
- const rectangle& rect,
- const std::basic_string<T,traits,alloc>& str
- ) const
- {
- draw_string(c,rect, str, 0, 0, (std::basic_string<T,traits,alloc>::npos),
- rectangle(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(),
- std::numeric_limits<long>::max(), std::numeric_limits<long>::max()));
- }
-
- // ------------------------------------------------------------------------------------
-
- template <typename T, typename traits, typename alloc>
- const rectangle compute_cursor_rect (
- const rectangle& rect,
- const std::basic_string<T,traits,alloc>& str,
- unsigned long index,
- typename std::basic_string<T,traits,alloc>::size_type first = 0,
- typename std::basic_string<T,traits,alloc>::size_type last = (std::basic_string<T,traits,alloc>::npos)
- ) const
- {
- typedef std::basic_string<T,traits,alloc> string;
- DLIB_ASSERT ( (last == string::npos) || (first <= last && last < str.size()) ,
- "\trectangle font::compute_cursor_rect()"
- << "\n\tlast == string::npos: " << ((last == string::npos)?"true":"false")
- << "\n\tfirst: " << (unsigned long)first
- << "\n\tlast: " << (unsigned long)last
- << "\n\tindex: " << index
- << "\n\tstr.size(): " << (unsigned long)str.size() );
-
- const font& f = *this;
-
- if (last == string::npos)
- last = str.size()-1;
-
- long x = f.left_overflow();
- long y = 0;
- int count = 0;
-
- if (str.size() != 0)
- {
- for (typename string::size_type i = first; i <= last && i < index; ++i)
- {
- ++count;
- if (str[i] == '\n')
- {
- x = f.left_overflow();
- y += f.height();
- count = 0;
- }
- else if (is_combining_char(str[i]) == false &&
- str[i] != '\r')
- {
- x += f[str[i]].width();
- }
- }
- }
-
- x += rect.left();
- y += rect.top();
-
- // if the cursor is at the start of a line then back it up one pixel
- if (count == 0)
- --x;
-
- return rectangle(x,y,x,y+f.height()-1);
- }
-
- // ------------------------------------------------------------------------------------
-
- template <typename T, typename traits, typename alloc>
- unsigned long compute_cursor_pos (
- const rectangle& rect,
- const std::basic_string<T,traits,alloc>& str,
- long x,
- long y,
- typename std::basic_string<T,traits,alloc>::size_type first = 0,
- typename std::basic_string<T,traits,alloc>::size_type last = (std::basic_string<T,traits,alloc>::npos)
- ) const
- {
- typedef std::basic_string<T,traits,alloc> string;
- DLIB_ASSERT ( (last == string::npos) || (first <= last && last < str.size()) ,
- "\tunsigned long font::compute_cursor_pos()"
- << "\n\tlast == string::npos: " << ((last == string::npos)?"true":"false")
- << "\n\tfirst: " << (unsigned long)first
- << "\n\tlast: " << (unsigned long)last
- << "\n\tx: " << x
- << "\n\ty: " << y
- << "\n\tstr.size(): " << (unsigned long)str.size() );
- const font& f = *this;
-
-
- if (str.size() == 0)
- return 0;
- else if (first >= str.size())
- return static_cast<unsigned long>(str.size());
-
- y -= rect.top();
- x -= rect.left();
- if (y < 0)
- y = 0;
- if (x < 0)
- x = 0;
-
- if (last == string::npos)
- last = str.size()-1;
-
-
- // first figure out what line we are on
- typename string::size_type pos = first;
- long line = 0;
- while (static_cast<unsigned long>(y) >= f.height())
- {
- ++line;
- y -= f.height();
- }
-
- // find the start of the given line
- for (typename string::size_type i = first; i <= last && line != 0; ++i)
- {
- if (str[i] == '\n')
- {
- --line;
- pos = i + 1;
- }
- }
-
-
- // now str[pos] == the first character of the start of the line
- // that contains the cursor.
- const typename string::size_type start_of_line = pos;
-
-
- long cur_x = f.left_overflow();
- // set the current cursor position to where the mouse clicked
- while (pos <= last)
- {
- if (x <= cur_x || str[pos] == '\n')
- break;
-
- if (is_combining_char(str[pos]) == false &&
- str[pos] != '\r')
- {
- cur_x += f[str[pos]].width();
- }
- ++pos;
- }
-
- if (x <= cur_x)
- {
- if (pos != start_of_line)
- {
- // we might actually be closer to the previous character
- // so check for that and if so then jump us back one.
- const long width = f[str[pos-1]].width();
- if (x < cur_x - width/2)
- --pos;
- }
- }
- return static_cast<unsigned long>(pos);
- }
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- const std::shared_ptr<font> get_native_font ();
-
-// ----------------------------------------------------------------------------------------
-
- class default_font : public font
- {
- letter* l;
-
-
- default_font(
- );
- default_font(default_font&); // copy constructor
- default_font& operator=(default_font&); // assignment operator
-
-
-
- public:
- static const std::shared_ptr<font>& get_font (
- )
- {
- static mutex m;
- static std::shared_ptr<font> f;
- auto_mutex M(m);
- if (f.get() == 0)
- f.reset(new default_font);
-
- return f;
- }
-
- ~default_font(
- )
- {
- delete [] l;
- }
-
- unsigned long height (
- ) const { return 16; }
-
- unsigned long ascender (
- ) const { return 12; }
-
- unsigned long left_overflow (
- ) const { return 1; }
-
- unsigned long right_overflow (
- ) const { return 2; }
-
- bool has_character (
- unichar ch
- )const
- {
- if (ch < 256 && (l[ch].width() != 0 || l[ch].num_of_points() != 0))
- return true;
- else
- return false;
- }
-
- const letter& operator[] (
- unichar ch
- ) const
- {
- if(ch < 256)
- return l[ch];
- return l[0]; // just return one of the empty characters in this case
- }
- };
-
-
-// ----------------------------------------------------------------------------------------
-
- class bdf_font : public font
- {
-
- public:
- bdf_font( long default_char_ = -1 );
-
- long read_bdf_file( std::istream& in, unichar max_enc, unichar min_enc = 0 );
- unsigned long height() const
- {
- return fbb.height();
- }
- unsigned long ascender() const
- {
- return std::max( 0L, 1 - fbb.top() );
- }
- unsigned long left_overflow() const
- {
- return std::max( 0L, -fbb.left() );
- }
- unsigned long right_overflow() const
- {
- return right_overflow_;
- }
- const letter& operator[] ( unichar uch ) const
- {
- if ( !has_character(uch) )
- {
- return gl[default_char];
- }
- return gl[uch];
- }
-
- bool has_character (
- unichar ch
- )const
- {
- if (ch < gl.size() && (gl[ch].width() != 0 || gl[ch].num_of_points() != 0))
- return true;
- else
- return false;
- }
-
- void adjust_metrics();
- private:
-
- bool bitmap_to_letter( array2d<char>& bitmap, unichar enc, unsigned long width, int x_offset, int y_offset );
-
- array<letter> gl;
- unichar default_char; // if (is_intialized == true), then this MUST be an actual glyph
- bool is_initialized;
- rectangle fbb;
- unsigned long right_overflow_;
-
- unsigned global_width;
- bool has_global_width;
- long specified_default_char;
-
- bdf_font( bdf_font& ); // copy constructor
- bdf_font& operator=( bdf_font& ); // assignment operator
-
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "fonts.cpp"
-#endif
-
-#endif // DLIB_FONTs_
-
diff --git a/ml/dlib/dlib/gui_widgets/fonts_abstract.h b/ml/dlib/dlib/gui_widgets/fonts_abstract.h
deleted file mode 100644
index df194bccd..000000000
--- a/ml/dlib/dlib/gui_widgets/fonts_abstract.h
+++ /dev/null
@@ -1,492 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), Nils Labugt, Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_FONTs_ABSTRACT_
-#ifdef DLIB_FONTs_ABSTRACT_
-
-#include "../gui_core.h"
-#include <string>
-#include "../serialize.h"
-#include "../unicode.h"
-#include <iostream>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class letter
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a letter in a font. It tells you the nominal
- width of the letter and which pixels form the letter.
-
- THREAD SAFETY
- const versions of this object are thread safe but if you are going to
- be modifying it then you must serialize access to it.
- !*/
- public:
- struct point
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents one of the pixels of a letter.
-
- The origin (i.e. (0,0)) of the coordinate plane is at the left
- side of the letter's baseline. Also note that y is negative when
- above the baseline and positive below (it is zero on the baseline
- itself).
-
- The x value is positive going to the right and negative to the left.
- The meaning of a negative x value is that any points with a negative
- x value will overlap with the preceding letter.
- !*/
-
- point (
- );
- /*!
- ensures
- - This constructor does nothing. The value of x and y
- are undefined after its execution.
- !*/
-
- point (
- signed char x_,
- signed char y_
- );
- /*!
- ensures
- - #x == x_
- - #y == y_
- !*/
-
-
- signed char x;
- signed char y;
- };
-
- // ---------------------------------
-
- letter (
- );
- /*!
- ensures
- - #width() == 0
- - #num_of_points() == 0
- !*/
-
- letter (
- unsigned short width_,
- unsigned short point_count
- );
- /*!
- ensures
- - #width() == width_
- - #num_of_points() == point_count
- !*/
-
- ~letter(
- );
- /*!
- ensures
- - any resources used by *this have been freed
- !*/
-
- const unsigned short width (
- ) const;
- /*!
- ensures
- - returns the width reserved for this letter in pixels. This is the
- number of pixels that are reserved for this letter between adjoining
- letters. It isn't necessarily the width of the actual letter itself.
- (for example, you can make a letter with a width less than how wide it
- actually is so that it overlaps with its neighbor letters.)
- !*/
-
- const unsigned short num_of_points (
- ) const;
- /*!
- ensures
- - returns the number of pixels that make up this letter.
- !*/
-
- point& operator[] (
- unsigned short i
- );
- /*!
- requires
- - i < num_of_points()
- ensures
- - returns a non-const reference to the ith point in this letter.
- !*/
-
- const point& operator[] (
- unsigned short i
- ) const;
- /*!
- requires
- - i < num_of_points()
- ensures
- - returns a const reference to the ith point in this letter.
- !*/
-
- void swap (
- letter& item
- );
- /*!
- ensures
- - swaps *this with item
- !*/
-
- private:
-
- // restricted functions
- letter(letter&); // copy constructor
- letter& operator=(letter&); // assignment operator
- };
-
- inline void swap (
- letter& a,
- letter& b
- ) { a.swap(b); }
- /*!
- provides a global swap
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- void serialize (
- const letter& item,
- std::ostream& out
- );
- /*!
- provides serialization support for letter objects
- !*/
-
- void deserialize (
- letter& item,
- std::istream& in
- );
- /*!
- provides deserialization support for letter objects
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- class font
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object defines an interface for a font type. It provides metrics
- for the font and functions to help you draw strings on a canvas object.
-
- THREAD SAFETY
- All the functions in this class are thread safe.
- !*/
-
- public:
-
- virtual bool has_character (
- unichar ch
- )const=0;
- /*!
- ensures
- - if (this font has a glyph for the given character) then
- - returns true
- - else
- - returns false
- !*/
- bool has_character(char ch) const { return this->has_character(zero_extend_cast<unichar>(ch)); }
- bool has_character(wchar_t ch) const { return this->has_character(zero_extend_cast<unichar>(ch)); }
- /* Cast char and wchar_t to unichar correctly when char or wchar_t is a signed type */
-
- virtual const letter& operator[] (
- unichar ch
- )const=0;
- /*!
- ensures
- - if (has_character(ch) == true) then
- - returns a letter object that tells you how to draw this character.
- - else
- - returns some default glyph for characters that aren't in this font.
- !*/
- const letter& operator[] (char ch) const { return (*this)[zero_extend_cast<unichar>(ch)]; };
- const letter& operator[] (wchar_t ch) const { return (*this)[zero_extend_cast<unichar>(ch)]; };
- /* Cast char and wchar_t to unichar correctly when char or wchar_t is a signed type */
-
- virtual const unsigned long height (
- ) const = 0;
- /*!
- ensures
- - returns the height in pixels of the tallest letter in the font
- !*/
-
- virtual const unsigned long ascender (
- ) const = 0;
- /*!
- ensures
- - returns the height() minus the number of pixels below the baseline used
- by the letter that hangs the lowest below the baseline.
- !*/
-
- virtual const unsigned long left_overflow (
- ) const = 0;
- /*!
- ensures
- - returns how far outside and to the left of its width a letter
- from this font may set pixels. (i.e. how many extra pixels to its
- left may a font use)
- !*/
-
- virtual const unsigned long right_overflow (
- ) const = 0;
- /*!
- ensures
- - returns how far outside and to the right of its width a letter
- from this font may set pixels. (i.e. how many extra pixels to its
- right may a font use)
- !*/
-
- template <typename T, typename traits, typename alloc>
- void compute_size (
- const std::basic_string<T,traits,alloc>& str,
- unsigned long& width,
- unsigned long& height,
- typename std::basic_string<T,traits,alloc>::size_type first = 0,
- typename std::basic_string<T,traits,alloc>::size_type last = std::basic_string<T,traits,alloc>::npos
- ) const;
- /*!
- requires
- - if (last != std::basic_string<T,traits,alloc>::npos) then
- - first <= last
- - last < str.size()
- ensures
- - all characters in str with an index < first are ignored by this
- function.
- - if (last != std::basic_string<T,traits,alloc>::npos) then
- - all characters in str with an index > last are ignored by
- this function.
- - if (str.size() == 0) then
- - #width == 0
- - #height == 0
- - else
- - #width == sum of the widths of the characters in the widest
- line in str + left_overflow() + right_overflow().
- - #height == (count(str.begin(),str.end(),'\n')+1)*height()
- !*/
-
- template <typename T, typename traits, typename alloc, typename pixel_type>
- void draw_string (
- const canvas& c,
- const rectangle& rect,
- const std::basic_string<T,traits,alloc>& str,
- const pixel_type& color = rgb_pixel(0,0,0),
- typename std::basic_string<T,traits,alloc>::size_type first = 0,
- typename std::basic_string<T,traits,alloc>::size_type last = std::basic_string<T,traits,alloc>::npos,
- const rectangle area = rectangle(-infinity,-infinity,infinity,infinity)
- ) const;
- /*!
- requires
- - if (last != std::basic_string<T,traits,alloc>::npos) then
- - first <= last
- - last < str.size()
- ensures
- - all characters in str with an index < first are ignored by this
- function.
- - if (last != std::basic_string<T,traits,alloc>::npos) then
- - all characters in str with an index > last are ignored by
- this function.
- - if (str.size() == 0) then
- - does nothing
- - else
- - draws str on the given canvas at the position defined by rect.
- Also uses the given pixel colors for the font color.
- - If the string is too big to fit in rect then the right and
- bottom sides of it will be clipped to make it fit.
- - only the part of the string that is contained inside the area
- rectangle will be drawn
- !*/
-
- template <typename T, typename traits, typename alloc>
- const rectangle compute_cursor_rect (
- const rectangle& rect,
- const std::basic_string<T,traits,alloc>& str,
- unsigned long index,
- typename std::basic_string<T,traits,alloc>::size_type first = 0,
- typename std::basic_string<T,traits,alloc>::size_type last = std::basic_string<T,traits,alloc>::npos
- ) const;
- /*!
- requires
- - if (last != std::basic_string<T,traits,alloc>::npos) then
- - first <= last
- - last < str.size()
- ensures
- - the returned rectangle has a width of 1 and a
- height of this->height().
- - computes the location of the cursor that would sit just before
- the character str[index] if str were drawn on the screen by
- draw_string(rect,str,...,first,last). The cursor location is
- returned in the form of a rectangle.
- - if (index < first) then
- - the returned cursor will be just before the character str[first].
- - if (last != std::basic_string<T,traits,alloc>::npos && index > last) then
- - the returned cursor will be just after the character str[last]
- - if (str.size() == 0) then
- - the returned cursor will be just at the start of the rectangle where
- str would be drawn if it wasn't empty.
- - if (index > str.size()-1) then
- - the returned cursor will be just after the character str[str.size()-1]
- !*/
-
- template <typename T, typename traits, typename alloc>
- const unsigned long compute_cursor_pos (
- const rectangle& rect,
- const std::basic_string<T,traits,alloc>& str,
- long x,
- long y,
- typename std::basic_string<T,traits,alloc>::size_type first = 0,
- typename std::basic_string<T,traits,alloc>::size_type last = std::basic_string<T,traits,alloc>::npos
- ) const;
- /*!
- requires
- - if (last != std::basic_string<T,traits,alloc>::npos) then
- - first <= last
- - last < str.size()
- ensures
- - returns a number idx that has the following properties:
- - if (first < str.size()) then
- - first <= idx
- - else
- - idx == str.size()
- - if (last != std::basic_string<T,traits,alloc>::npos) then
- - idx <= last + 1
- - compute_cursor_rect(rect,str,idx,first,last) == the cursor
- position that is closest to the pixel (x,y)
- !*/
-
-
- private:
-
- // restricted functions
- font(font&); // copy constructor
- font& operator=(font&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class default_font : public font
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an implementation of the Helvetica 12 point font.
-
- THREAD SAFETY
- It is safe to call get_font() and access the returned font from any
- thread and no synchronization is needed as long as it is called
- after the main() function has been entered.
- !*/
-
- public:
- static const shared_ptr_thread_safe<font> get_font(
- );
- /*!
- ensures
- - returns an instance of this font.
- throws
- - std::bad_alloc
- This exception is thrown if there is a problem gathering the needed
- memory for the font object.
- !*/
-
- private:
-
- // restricted functions
- default_font(); // normal constructor
- default_font(default_font&); // copy constructor
- default_font& operator=(default_font&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class bdf_font : public font
- {
-
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is a font object that is capable of loading of loading BDF (Glyph
- Bitmap Distribution Format) font files.
-
- THREAD SAFETY
- If you only access this object via the functions in the parent class font
- then this object is thread safe. But if you need to call any of the
- functions introduced in this derived class then you need to serialize
- access to this object while you call these functions.
- !*/
-
- public:
-
- bdf_font(
- long default_char = -1
- );
- /*!
- ensures
- - for all x:
- - #has_character(x) == false
- (i.e. this font starts out empty. You have to call read_bdf_file()
- to load it with data)
- - if (default_char == -1) then
- - the letter returned by (*this)[ch] for values of
- ch where has_character(ch) == false will be the
- default glyph defined in the bdf file.
- - else
- - the letter returned by (*this)[ch] for values of
- ch where has_character(ch) == false will be the
- letter (*this)[default_char].
- !*/
-
- long read_bdf_file(
- std::istream& in,
- unichar max_enc,
- unichar min_enc = 0
- );
- /*!
- ensures
- - attempts to read the font data from the given input stream into
- *this. The input stream is expected to contain a valid BDF file.
- - reads in characters with encodings in the range min_enc to max_enc
- into this font. All characters in the font file outside this range
- are ignored.
- - returns the number of characters loaded into this font from the
- given input stream.
- !*/
-
- void adjust_metrics();
- /*!
- ensures
- - Computes metrics based on actual glyphs loaded, instead of using
- the values in the bdf file header. (May be useful if loading glyphs
- from more than one file or a small part of a file.)
- !*/
-
- private:
-
- bdf_font( bdf_font& ); // copy constructor
- bdf_font& operator=( bdf_font& ); // assignment operator
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- const shared_ptr_thread_safe<font> get_native_font(
- );
- /*!
- ensures
- - returns a font object that uses the local font
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_FONTs_ABSTRACT_
-
diff --git a/ml/dlib/dlib/gui_widgets/nativefont.h b/ml/dlib/dlib/gui_widgets/nativefont.h
deleted file mode 100644
index 2de0edfaa..000000000
--- a/ml/dlib/dlib/gui_widgets/nativefont.h
+++ /dev/null
@@ -1,612 +0,0 @@
-// Copyright (C) 2006 Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_IGG_FONT_RENDERER_H_
-#define DLIB_IGG_FONT_RENDERER_H_
-#include "../platform.h"
-
-
-#include "../gui_widgets.h"
-#include "../unicode.h"
-#include "../uintn.h"
-
-#include <map>
-#include <memory>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <locale.h>
-
-#if defined(WIN32)
-#include <windows.h>
-#include <mbstring.h>
-#elif defined(POSIX)
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xlocale.h>
-#endif
-
-namespace nativefont
-{
-// ----------------------------------------------------------------------------------------
-
- namespace font_renderer
- {
- typedef dlib::uint8 byte;
-
-
-#ifdef WIN32
- template <typename T> struct input2native_trait{
- };
- template <> struct input2native_trait<char>{
- typedef char type_t;
- };
- template <> struct input2native_trait<wchar_t>{
- typedef wchar_t type_t;
- };
- template <> struct input2native_trait<dlib::unichar>{
- typedef wchar_t type_t;
- };
-#endif
- // T : N : sizeof_source_type
- template <int N> struct size2inner_trait{
- };
- template <> struct size2inner_trait<1>{
- typedef char type_t;
- };
- template <> struct size2inner_trait<2>{
- typedef dlib::uint16 type_t;
- };
- template <> struct size2inner_trait<4>{
- typedef dlib::unichar type_t;
- };
-
-
-// ----------------------------------------------------------------------------------------
-
- template <int N> struct create_helper{ };
- template <> struct create_helper<1>{
- typedef char type_t;
- type_t *istr;
- int len;
- create_helper(char *str){
- len = (int)strlen(str);
- istr = str;
- }
- ~create_helper(){}
- };
- template <> struct create_helper<2>{
- typedef wchar_t type_t;
- type_t *istr;
- bool allocated;
- int len;
- create_helper(wchar_t *str){
- allocated = false;
- len = (int)wcslen(str);
- istr = str;
- }
- create_helper(dlib::unichar *str){
- allocated = true;
- len = 0;
- int unicount = 0;
- dlib::unichar *p = str;
- while(*p){
- if (*p > 0xffff){
- len += 2;
- }else{
- len++;
- }
- unicount++;
- p++;
- }
- istr = new wchar_t[len+1];
- for (int i = 0, wi = 0; i < unicount; ++i){
- dlib::unichar high, low;
- if (str[i] > 0xffff){
- dlib::unichar_to_surrogate_pair(str[i], high, low);
- istr[wi] = (wchar_t)high, istr[wi+1] = (wchar_t)low;
- wi += 2;
- }else{
- istr[wi] = (wchar_t)str[i];
- wi += 1;
- }
- }
- istr[len] = L'\0';
- }
-
- ~create_helper(){
- if (allocated) delete[] istr;
- }
- };
- template <> struct create_helper<4>{
- typedef wchar_t type_t;
- type_t *istr;
- int len;
- create_helper(dlib::unichar *str){
- len = (int)wcslen((wchar_t *)str);
- istr = (type_t *)str;
- }
- ~create_helper(){}
- };
-
-// ----------------------------------------------------------------------------------------
-
- class font_renderer{
- public:
-
- struct rgb_type{
- byte r, g, b;
- rgb_type() : r(0), g(0), b(0){};
- rgb_type(byte r_, byte g_, byte b_) : r(r_), g(g_), b(b_){};
- };
- private:
-
- byte *image;
- int width, height;
- void destroy(){
- width = height = 0;
- delete image;
- image = 0;
- }
- struct vals_internal{
- int width, height;
-#ifdef WIN32
- COLORREF rgb2RGB(rgb_type &rgb){
- return RGB(rgb.r, rgb.g, rgb.b);
- }
- HBITMAP hBmp, hBmpOld;
- HDC hDCBmp;
- BYTE *pixelint;
- HFONT hFont, hFontOld;
- HBRUSH hBrush;
- int pix_width_prev, pix_height_prev;
- bool first;
- int ascender, descender;
- int height_prev;
- char attribute_prev;
-
- template <typename T> void create(T *str, int height_want, bool italic, bool bold, bool fixed, rgb_type &background, rgb_type &foreground){
- struct inner{
- inline static BOOL GetTextExtentPoint32(HDC hDC, LPCSTR str, int len, LPSIZE lpsize){
- return ::GetTextExtentPoint32A(hDC, str, len, lpsize);
- }
- inline static BOOL GetTextExtentPoint32(HDC hDC, LPCWSTR str, int len, LPSIZE lpsize){
- return ::GetTextExtentPoint32W(hDC, str, len, lpsize);
- }
- inline static BOOL TextOut(HDC hDC, int nxstart, int nystart, LPCSTR str, int cbstr){
- return ::TextOutA(hDC, nxstart, nystart, str, cbstr);
- }
- inline static BOOL TextOut(HDC hDC, int nxstart, int nystart, LPCWSTR str, int cbstr){
- return ::TextOutW(hDC, nxstart, nystart, str, cbstr);
- }
- };
-
- create_helper<sizeof(typename input2native_trait<T>::type_t)> ch(str);
-
- if (hDCBmp == NULL){
- HWND hWnd = GetDesktopWindow();
- HDC hDC = GetDC(hWnd);
- hDCBmp = CreateCompatibleDC(hDC);
- ReleaseDC(hWnd, hDC);
- }
- SetTextColor(hDCBmp, rgb2RGB(foreground));
- SetBkColor(hDCBmp, rgb2RGB(background));
-
- char attribute = (italic ? 1 : 0) | (bold ? 2 : 0) | (fixed ? 4 : 0);
- if (!hFont || height_prev != height || attribute != attribute_prev){
- attribute_prev = attribute;
- height_prev = height_want;
- if (hFont){
- SelectObject(hDCBmp, hFontOld);
- DeleteObject(hFont);
- }
- hFont = CreateFont(height_want, 0, 0, 0, bold ? FW_BOLD : FW_DONTCARE, italic ? TRUE : FALSE,
- FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
- fixed ? (FIXED_PITCH | FF_DONTCARE) : (VARIABLE_PITCH | FF_DONTCARE), NULL);
- hFontOld = (HFONT)SelectObject(hDCBmp, hFont);
- }
-
- {
- SIZE sz;
- inner::GetTextExtentPoint32(hDCBmp, ch.istr, ch.len, &sz);
- width = ((sz.cx + 3) / 4) * 4;
- height = sz.cy;
- }
-
- if (pix_width_prev < width || pix_height_prev < height){
- if (hBmp){
- SelectObject(hDCBmp, hBmpOld);
- DeleteObject(hBmp);
- }
- pix_width_prev = width * 2;
- pix_height_prev = height * 2;
- BITMAPINFO bi;
- ZeroMemory(&bi, sizeof(bi));
- bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi.bmiHeader.biBitCount = 24;
- bi.bmiHeader.biPlanes = 1;
- bi.bmiHeader.biWidth = pix_width_prev;
- bi.bmiHeader.biHeight = -pix_height_prev;
- hBmp = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void **)&pixelint, NULL, 0);
- hBmpOld = (HBITMAP)SelectObject(hDCBmp, hBmp);
- }
-
- {
- HBRUSH hBrush = CreateSolidBrush(rgb2RGB(background));
- RECT rc;
- rc.left = rc.top = 0;
- rc.right = pix_width_prev;
- rc.bottom = pix_height_prev;
- FillRect(hDCBmp, &rc, hBrush);
- }
-
- inner::TextOut(hDCBmp, 0, 0, ch.istr, ch.len);
- TEXTMETRICW tm;
- GetTextMetricsW(hDCBmp,&tm);
- ascender = tm.tmAscent;
- descender = tm.tmDescent;
- }
-
- template <typename T> vals_internal(T *str, int height_want, bool italic = false,
- bool bold = false, bool fixed = false, rgb_type background = rgb_type(), rgb_type foreground = rgb_type()){
- first = true;
- hFont = NULL;
- hDCBmp = 0;
- hBmpOld = 0;
- hBmp = 0;
- hDCBmp = 0;
- pixelint = 0;
- pix_width_prev = pix_height_prev = 0;
- height_prev = -1;
- attribute_prev = 0;
- create(str, height_want, italic, bold, fixed, background, foreground);
- first = false;
- }
-
- inline int get_ascender(){
- return ascender;
- }
-
- inline int get_descender(){
- return descender;
- }
-
- inline void get_pixel(int x, int y, byte &r, byte &g, byte &b){
- byte *p = pixelint + (y * pix_width_prev + x) * 3;
- r = *(p+2), g = *(p+1), b = *p;
- }
-
- void destroy(){
- SelectObject(hDCBmp, hBmpOld);
- DeleteObject(hBmp);
- SelectObject(hDCBmp, hFontOld);
- DeleteObject(hFont);
- DeleteDC(hDCBmp);
- hFont = NULL;
- hDCBmp = 0;
- hBmpOld = 0;
- hBmp = 0;
- hDCBmp = 0;
- pixelint = 0;
- }
- ~vals_internal(){
- destroy();
- }
-#elif defined(POSIX)
- XImage *ximg;
- Display *d;
- GC gc;
- XFontSet fs;
- Pixmap pix;
- Colormap cmap;
- int ascender, descender;
- int pix_width_prev, pix_height_prev;
- char fontset_prev[256];
- unsigned long rgb2color(rgb_type col, Display *d, Colormap &cmap){
- XColor xcol;
- xcol.red = col.r * 257;
- xcol.green = col.g * 257;
- xcol.blue = col.b * 257;
- XAllocColor(d, cmap, &xcol);
- return xcol.pixel;
- }
- template <typename T> void create(T *str, int height_want, bool italic, bool bold, bool fixed, rgb_type background, rgb_type foreground){
- struct inner{
- inline static int XTextExtents (XFontSet fs, char *str, int len, XRectangle *ink, XRectangle *logical){
- return XmbTextExtents(fs, str, len, ink, logical);
- }
- inline static int XTextExtents (XFontSet fs, wchar_t *str, int len, XRectangle *ink, XRectangle *logical){
- return XwcTextExtents(fs, str, len, ink, logical);
- }
- inline static void XDrawString(Display *d, Window w, XFontSet fs, GC gc, int x, int y, char *str, int num_bytes){
- XmbDrawString(d, w, fs, gc, x, y, str, num_bytes);
- }
- inline static void XDrawString(Display *d, Window w, XFontSet fs, GC gc, int x, int y, wchar_t *str, int num_bytes){
- XwcDrawString(d, w, fs, gc, x, y, str, num_bytes);
- }
- };
- create_helper<sizeof(T)> ch((typename size2inner_trait<sizeof(T)>::type_t *)str);
- setlocale(LC_CTYPE, "");
- if (d == NULL){
- d = XOpenDisplay(NULL);
- if (d == 0)
- {
- d = XOpenDisplay(":0.0");
- if (d == 0)
- {
- throw dlib::gui_error("Unable to connect to the X display.");
- }
- }
-
- cmap = DefaultColormap(d, DefaultScreen(d));
- }
- char fontset[256];
- {
- char *p = fontset;
- p += sprintf(fontset, "-*-*-%s-%c-normal--%d-*-*-*-%c",
- bold ? "bold" : "medium", italic ? 'i' : 'r', height_want, fixed ? 'c' : 'p');
- if (fixed){
- sprintf(p, ",-*-*-%s-%c-normal--%d-*-*-*-m",
- bold ? "bold" : "medium", italic ? 'i' : 'r', height_want);
- }
- }
- bool equal_font;
- if (strcmp(fontset, fontset_prev) == 0){
- equal_font = true;
- }else{
- equal_font = false;
- strcpy(fontset_prev, fontset);
- }
-
- char **mlist;
- int mcount;
- char *def_str;
- if (!equal_font){
- if (fs){
- XFreeFontSet(d, fs);
- }
- fs = XCreateFontSet(d, fontset, &mlist, &mcount, &def_str);
- if (fs == NULL)
- throw dlib::gui_error("gui_error: XCreateFontSet() failure");
-
- XFontSetExtents *extent;
- extent = XExtentsOfFontSet(fs);
- ascender = -extent->max_logical_extent.y;
- descender = extent->max_logical_extent.height - ascender;
- XFreeStringList(mlist);
- }
- XRectangle ink, logical;
- inner::XTextExtents (fs, ch.istr, ch.len, &ink, &logical);
- width = logical.width;
- height = height_want;
-
- if (pix == None || pix_width_prev < width || pix_height_prev < height){
- if (pix != None){
- XFreeGC(d, gc);
- XFreePixmap(d, pix);
- }
- pix_width_prev = width * 2;
- pix_height_prev = height * 2;
- pix = XCreatePixmap(d, DefaultRootWindow(d), pix_width_prev, pix_height_prev, XDefaultDepth(d, DefaultScreen(d)));
- gc = XCreateGC(d, pix, 0, NULL);
- }
-
- unsigned long backcolor = rgb2color(background, d, cmap);
- XSetForeground(d, gc, backcolor);
- XSetBackground(d, gc, backcolor);
- XFillRectangle(d, pix, gc, 0, 0, width, height);
- XSetForeground(d, gc, rgb2color(foreground, d, cmap));
- inner::XDrawString(d, pix, fs, gc, 0, ascender, ch.istr, ch.len);
-
- if (ximg) XDestroyImage(ximg);
- ximg = XGetImage(d, pix, 0, 0, width, height, AllPlanes, ZPixmap );
- }
-
- template <typename T> vals_internal(T *str, int height_want, bool italic = false,
- bool bold = false, bool fixed = false, rgb_type background = rgb_type(), rgb_type foreground = rgb_type()){
- fontset_prev[0] = '\0';
- ximg = NULL;
- d = NULL;
- pix = None;
- fs = NULL;
- ascender = descender = -1;
- pix_width_prev = pix_height_prev = -1;
- create(str, height_want, italic, bold, fixed, background, foreground);
- }
-
- inline int get_ascender(){
- return ascender;
- }
-
- inline int get_descender(){
- return descender;
- }
-
- std::map<unsigned long,rgb_type> col2rgb;
- rgb_type color2rgb(unsigned long color, Display *d, Colormap &cmap){
- if (col2rgb.count(color)){
- return col2rgb[color];
- }else{
- XColor xcol;
- xcol.pixel = color;
- XQueryColor(d, cmap, &xcol);
- rgb_type rgb_((byte)(xcol.red/257), (byte)(xcol.green/257), (byte)(xcol.blue/257));
- col2rgb[color] = rgb_;
- return rgb_;
- }
- }
- inline void get_pixel(int x, int y, byte &r, byte &g, byte &b){
- rgb_type c = color2rgb(XGetPixel(ximg,x,y), d, cmap);
- r = c.r, g = c.g, b = c.b;
- }
-
- ~vals_internal(){
- XDestroyImage(ximg);
-
- XFreeGC(d, gc);
- XFreeFontSet(d, fs);
- XFreePixmap(d, pix);
- XCloseDisplay(d);
- }
-#endif
- };
-
- struct image_size_setter{
- void operator()(int&, int&){
- }
- };
-
- int ascender, descender;
- vals_internal *vi;
- public:
- font_renderer() : image(0), width(0), height(0){
- ascender = descender = 0;
- vi = NULL;
- }
-
- template<typename T> font_renderer(T *str, int height_want, bool italic = false, bool bold = false, bool fixed = false, rgb_type background = rgb_type(0,0,0), rgb_type foreground = rgb_type(255,255,255)){
- render(str, height_want, italic, bold, fixed, background, foreground);
- }
-
- template<typename T> void render(T *str, int height_want,
- bool italic = false, bool bold = false, bool fixed = false,
- rgb_type background = rgb_type(0,0,0), rgb_type foreground = rgb_type(255,255,255)){
- if (vi == NULL){
- vi = new vals_internal(str, height_want, italic, bold, fixed, background, foreground);
- }else{
- vi->create(str, height_want, italic, bold, fixed, background, foreground);
- }
- width = vi->width, height = vi->height;
- image = new byte[width * height * 3];
- ascender = vi->get_ascender();
- descender = vi->get_descender();
-
- int h = height, w = width;
- for (int j = 0, i3 = 0; j < h; ++j){
- for (int i = 0; i < w; ++i, i3 += 3){
- vi->get_pixel(i, j, image[i3], image[i3+1], image[i3+2]);
- }
- }
- }
-
- ~font_renderer(){
- if (vi) delete vi;
- destroy();
- }
- int get_width(){
- return width;
- }
- int get_height(){
- return height;
- }
- inline int get_ascender(){
- return ascender;
- }
- inline int get_descender(){
- return descender;
- }
-
- const byte *get_image(){
- return image;
- }
- };
- }
-
-// ----------------------------------------------------------------------------------------
-
- class native_font : public dlib::font
- {
- unsigned long ascender_;
- native_font(){
- setlocale(LC_CTYPE, "");
- ascender_ = 0;
- get_letter((int)('x'));
- }
- typedef std::map<int,dlib::letter *> letters_map_type;
- letters_map_type letters;
- font_renderer::font_renderer fl;
- public:
-
- virtual ~native_font()
- {
- // delete all the letter objects we have in our letters map
- letters_map_type::iterator i;
- for (i = letters.begin(); i != letters.end(); ++i)
- {
- delete i->second;
- }
- }
-
- virtual bool has_character (
- dlib::unichar ch
- )const{
- return (*this)[ch].width() > 0;
- }
-
- static const std::shared_ptr<font>& get_font (
- )
- {
- static std::shared_ptr<font> f(new native_font);
- return f;
- }
-
- virtual const dlib::letter& operator[] (dlib::unichar ch) const{
- return (const_cast<native_font *>(this))->get_letter(ch);
- }
-
- dlib::letter& get_letter (
- dlib::unichar ch
- ){
- if (letters.count(ch)){
- dlib::letter *l = letters.find(ch)->second;
- return *l;
- }
-
- dlib::unichar c[2];
- c[0] = ch;
- c[1] = 0;
-
- fl.render(c, height(),false,false,true);
- if (ascender_ == 0){
- ascender_ = fl.get_ascender();
- }
- std::vector<dlib::letter::point> v;
- const font_renderer::byte *bp = fl.get_image();
- for (int j = 0; j < fl.get_height(); ++j){
- for (int i = 0; i < fl.get_width(); ++i, bp += 3){
- if (*bp){
- v.push_back(dlib::letter::point(i,j-ascender()+1));
- }
- }
- }
- dlib::letter *l = new dlib::letter(fl.get_width(), (unsigned long)v.size());
-
- letters.insert(std::make_pair(ch,l));
- for (int i = 0; i < (int)v.size(); ++i){
- (*l)[i] = v.at(i);
- }
- return *l;
- }
-
- virtual unsigned long height (
- ) const { return 12; }
-
- virtual unsigned long ascender (
- ) const { return ascender_; }
-
- virtual unsigned long left_overflow (
- ) const { return 1; }
-
- virtual unsigned long right_overflow (
- ) const { return 2; }
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_IGG_FONT_RENDERER_H_
-
diff --git a/ml/dlib/dlib/gui_widgets/style.cpp b/ml/dlib/dlib/gui_widgets/style.cpp
deleted file mode 100644
index a3d22d10f..000000000
--- a/ml/dlib/dlib/gui_widgets/style.cpp
+++ /dev/null
@@ -1,998 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net), and Nils Labugt
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_WIDGETs_STYLE_CPP_
-#define DLIB_WIDGETs_STYLE_CPP_
-
-#include "style.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // button style stuff
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void button_style_default::draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long ,
- const long ,
- const ustring& name,
- const bool is_depressed
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- fill_rect(c,rect,rgb_pixel(212,208,200));
-
- unsigned char red, green, blue;
- if (enabled)
- {
- red = 0;
- green = 0;
- blue = 0;
- }
- else
- {
- red = 128;
- green = 128;
- blue = 128;
- }
-
- // compute the name length if it hasn't already been computed
- if (name_width == 0)
- {
- unsigned long height;
- mfont.compute_size(name,name_width,height);
- }
-
- // figure out where the name string should appear
- rectangle name_rect;
- const unsigned long width = name_width;
- const unsigned long height = mfont.height();
- name_rect.set_left((rect.right() + rect.left() - width)/2);
- name_rect.set_top((rect.bottom() + rect.top() - height)/2 + 1);
- name_rect.set_right(name_rect.left()+width-1);
- name_rect.set_bottom(name_rect.top()+height);
-
-
- if (is_depressed)
- {
- name_rect.set_left(name_rect.left()+1);
- name_rect.set_right(name_rect.right()+1);
- name_rect.set_top(name_rect.top()+1);
- name_rect.set_bottom(name_rect.bottom()+1);
-
- mfont.draw_string(c,name_rect,name,rgb_pixel(red,green,blue));
-
- draw_button_down(c,rect);
- }
- else
- {
- mfont.draw_string(c,name_rect,name,rgb_pixel(red,green,blue));
-
- // now draw the edge of the button
- draw_button_up(c,rect);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle button_style_default::
- get_min_size (
- const ustring& name,
- const font& mfont
- ) const
- {
-
- unsigned long width;
- unsigned long height;
- mfont.compute_size(name,width,height);
- name_width = width;
-
- return rectangle(width+2*padding, height+2*padding);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void button_style_toolbar1::draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- const long radius = 4;
-
- unsigned char red, green, blue;
- if (enabled)
- {
- red = 0;
- green = 0;
- blue = 0;
-
- long d = 0;
- if (rect.contains(lastx,lasty))
- d = -70;
-
- if (is_depressed)
- d = 20;
-
- if (d != 0)
- {
- rectangle temp(rect);
- temp.left()--; temp.top()--; temp.right()++; temp.bottom()++;
- draw_rounded_rectangle(c, temp, radius, rgb_alpha_pixel(255,255,0,120));
- temp.left()--; temp.top()--; temp.right()++; temp.bottom()++;
- draw_rounded_rectangle(c, temp, radius, rgb_alpha_pixel(255,255,0,40));
- }
-
- fill_gradient_rounded(c,rect,radius,rgb_alpha_pixel(255, 255, 255,120-d),
- rgb_alpha_pixel(255, 255, 255,0));
- draw_rounded_rectangle(c,rect,radius, rgb_alpha_pixel(30,30,30,200));
- }
- else
- {
- red = 128;
- green = 128;
- blue = 128;
- draw_rounded_rectangle(c,rect,radius, rgb_alpha_pixel(red,green,blue,210));
- }
-
-
- // compute the name length if it hasn't already been computed
- if (name_width == 0)
- {
- unsigned long height;
- mfont.compute_size(name,name_width,height);
- }
-
- // figure out where the name string should appear
- rectangle name_rect;
- const unsigned long width = name_width;
- const unsigned long height = mfont.height();
- name_rect.set_left((rect.right() + rect.left() - width)/2);
- name_rect.set_top((rect.bottom() + rect.top() - height)/2 + 1);
- name_rect.set_right(name_rect.left()+width-1);
- name_rect.set_bottom(name_rect.top()+height);
-
-
- if (is_depressed)
- {
- name_rect.set_left(name_rect.left()+1);
- name_rect.set_right(name_rect.right()+1);
- name_rect.set_top(name_rect.top()+1);
- name_rect.set_bottom(name_rect.bottom()+1);
-
- mfont.draw_string(c,name_rect,name,rgb_pixel(red,green,blue));
-
- }
- else
- {
- mfont.draw_string(c,name_rect,name,rgb_pixel(red,green,blue));
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle button_style_toolbar1::
- get_min_size (
- const ustring& name,
- const font& mfont
- ) const
- {
-
- unsigned long width;
- unsigned long height;
- mfont.compute_size(name,width,height);
- name_width = width;
-
- return rectangle(width+2*padding, height+2*padding);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void button_style_toolbar_icon1::draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& ,
- const long lastx,
- const long lasty,
- const ustring& ,
- const bool is_depressed
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- const long radius = padding;
-
- if (enabled)
- {
- if (rect.contains(lastx,lasty))
- {
- if (is_depressed)
- {
- fill_gradient_rounded(c,rect,radius,rgb_alpha_pixel(100,100,200,150),
- rgb_alpha_pixel(50,50,100,100));
- draw_rounded_rectangle(c,rect,radius, rgb_alpha_pixel(150,150,30,200));
- }
- else
- {
- fill_gradient_rounded(c,rect,radius,rgb_alpha_pixel(150,150,250,130),
- rgb_alpha_pixel(100,100,150,90));
- draw_rounded_rectangle(c,rect,radius, rgb_alpha_pixel(150,150,30,200));
- }
- }
-
- if (is_depressed)
- {
- rectangle img_rect(translate_rect(centered_rect(rect,img_mouseover.nc(),img_mouseover.nr()),1,1));
- point p(img_rect.left(),img_rect.top());
- draw_image(c,p,img_mouseover);
- }
- else
- {
- rectangle img_rect(centered_rect(rect,img_normal.nc(),img_normal.nr()));
- point p(img_rect.left(),img_rect.top());
- if (rect.contains(lastx,lasty))
- draw_image(c,p,img_mouseover);
- else
- draw_image(c,p,img_normal);
- }
-
- }
- else
- {
- rectangle img_rect(centered_rect(rect,img_normal.nc(),img_normal.nr()));
- point p(img_rect.left(),img_rect.top());
- draw_image(c,p,img_disabled);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle button_style_toolbar_icon1::
- get_min_size (
- const ustring& ,
- const font&
- ) const
- {
- return rectangle(img_normal.nc()+2*padding, img_normal.nr()+2*padding);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void button_style_arrow::
- draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& ,
- const long ,
- const long ,
- const ustring& ,
- const bool is_depressed
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- fill_rect(c,rect,rgb_pixel(212,208,200));
-
- const long height = rect.height();
- const long width = rect.width();
-
- const long smallest = (width < height) ? width : height;
-
- const long rows = (smallest+3)/4;
- const long start = rows + rows/2-1;
- long dep;
-
- long tip_x = 0;
- long tip_y = 0;
- long wy = 0;
- long hy = 0;
- long wx = 0;
- long hx = 0;
-
- if (is_depressed)
- {
- dep = 0;
-
- // draw the button's border
- draw_button_down(c,rect);
- }
- else
- {
- dep = -1;
-
- // draw the button's border
- draw_button_up(c,rect);
- }
-
-
- switch (dir)
- {
- case UP:
- tip_x = width/2 + rect.left() + dep;
- tip_y = (height - start)/2 + rect.top() + dep + 1;
- wy = 0;
- hy = 1;
- wx = 1;
- hx = 0;
- break;
-
- case DOWN:
- tip_x = width/2 + rect.left() + dep;
- tip_y = rect.bottom() - (height - start)/2 + dep;
- wy = 0;
- hy = -1;
- wx = 1;
- hx = 0;
- break;
-
- case LEFT:
- tip_x = rect.left() + (width - start)/2 + dep + 1;
- tip_y = height/2 + rect.top() + dep;
- wy = 1;
- hy = 0;
- wx = 0;
- hx = 1;
- break;
-
- case RIGHT:
- tip_x = rect.right() - (width - start)/2 + dep;
- tip_y = height/2 + rect.top() + dep;
- wy = 1;
- hy = 0;
- wx = 0;
- hx = -1;
- break;
- }
-
-
- rgb_pixel color;
- if (enabled)
- {
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- }
- else
- {
- color.red = 128;
- color.green = 128;
- color.blue = 128;
- }
-
-
-
- for (long i = 0; i < rows; ++i)
- {
- draw_line(c,point(tip_x + wx*i + hx*i, tip_y + wy*i + hy*i),
- point(tip_x + wx*i*-1 + hx*i, tip_y + wy*i*-1 + hy*i),
- color);
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // toggle button style stuff
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void toggle_button_style_default::draw_toggle_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long ,
- const long ,
- const ustring& name,
- const bool is_depressed,
- const bool is_checked
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- fill_rect(c,rect,rgb_pixel(212,208,200));
-
- unsigned char red, green, blue;
- if (enabled)
- {
- red = 0;
- green = 0;
- blue = 0;
- }
- else
- {
- red = 128;
- green = 128;
- blue = 128;
- }
-
- // compute the name length if it hasn't already been computed
- if (name_width == 0)
- {
- unsigned long height;
- mfont.compute_size(name,name_width,height);
- }
-
- // figure out where the name string should appear
- rectangle name_rect;
- const unsigned long width = name_width;
- const unsigned long height = mfont.height();
- name_rect.set_left((rect.right() + rect.left() - width)/2);
- name_rect.set_top((rect.bottom() + rect.top() - height)/2 + 1);
- name_rect.set_right(name_rect.left()+width-1);
- name_rect.set_bottom(name_rect.top()+height);
-
- long d = 0;
- if (is_checked)
- d = 1;
-
- if (is_depressed)
- d = 2;
-
- name_rect.set_left(name_rect.left()+d);
- name_rect.set_right(name_rect.right()+d);
- name_rect.set_top(name_rect.top()+d);
- name_rect.set_bottom(name_rect.bottom()+d);
-
- mfont.draw_string(c,name_rect,name,rgb_pixel(red,green,blue));
-
- // now draw the edge of the button
- if (is_checked || is_depressed)
- draw_button_down(c,rect);
- else
- draw_button_up(c,rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle toggle_button_style_default::
- get_min_size (
- const ustring& name,
- const font& mfont
- ) const
- {
-
- unsigned long width;
- unsigned long height;
- mfont.compute_size(name,width,height);
- name_width = width;
-
- return rectangle(width+2*padding, height+2*padding);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void toggle_button_style_check_box::draw_toggle_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long ,
- const long ,
- const ustring& name,
- const bool is_depressed,
- const bool is_checked
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
-
- rgb_pixel color;
- if (enabled)
- {
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- }
- else
- {
- color.red = 128;
- color.green = 128;
- color.blue = 128;
- }
-
-
- // figure out where the name string should appear
- rectangle name_rect, box_rect;
- unsigned long padding = 0;
- if (mfont.height() < 13)
- padding = (rect.height() - mfont.height())/2;
-
- name_rect = rect;
- name_rect.set_left(rect.left() + 17-1);
- name_rect.set_top(rect.top() + padding);
- name_rect.set_bottom(rect.bottom() - padding);
-
- box_rect = rect;
- box_rect.set_right(rect.left() + 12);
- box_rect.set_bottom(rect.top() + 12);
-
- mfont.draw_string(c,name_rect,name,color);
-
- if (enabled && is_depressed == false)
- fill_rect(c, box_rect,rgb_pixel(255,255,255));
- else
- fill_rect(c, box_rect,rgb_pixel(212,208,200));
-
- draw_sunken_rectangle(c, box_rect);
-
-
- if (is_checked)
- {
- const long x = box_rect.left();
- const long y = box_rect.top();
- draw_line(c,point(3+x,5+y),point(6+x,8+y),color);
- draw_line(c,point(3+x,6+y),point(5+x,8+y),color);
- draw_line(c,point(3+x,7+y),point(5+x,9+y),color);
- draw_line(c,point(6+x,6+y),point(9+x,3+y),color);
- draw_line(c,point(6+x,7+y),point(9+x,4+y),color);
- draw_line(c,point(6+x,8+y),point(9+x,5+y),color);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle toggle_button_style_check_box::
- get_min_size (
- const ustring& name,
- const font& mfont
- ) const
- {
- unsigned long width;
- unsigned long height;
- mfont.compute_size(name,width,height);
-
- if (height < 13)
- height = 13;
-
- return rectangle(width + 17 -1, height -1);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void toggle_button_style_radio_button::draw_toggle_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long ,
- const long ,
- const ustring& name,
- const bool is_depressed,
- const bool is_checked
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
-
- rgb_pixel color;
-
- // figure out where the name string should appear
- rectangle name_rect, box_rect;
- unsigned long padding = 0;
- if (mfont.height() < 13)
- padding = (rect.height() - mfont.height())/2;
-
- name_rect = rect;
- name_rect.set_left(rect.left() + 17-1);
- name_rect.set_top(rect.top() + padding);
- name_rect.set_bottom(rect.bottom() - padding);
-
- box_rect = rect;
- box_rect.set_right(rect.left() + 12);
- box_rect.set_bottom(rect.top() + 12);
-
-
- const long x = box_rect.left();
- const long y = box_rect.top();
-
- if (enabled && is_depressed == false)
- draw_solid_circle(c,point(rect.left()+5,rect.top()+5),4.5,rgb_pixel(255,255,255));
- else
- draw_solid_circle(c,point(rect.left()+5,rect.top()+5),4.5,rgb_pixel(212,208,200));
-
-
- color = rgb_pixel(128,128,128);
- draw_line(c,point(0+x,4+y),point(0+x,7+y),color);
- draw_line(c,point(1+x,2+y),point(1+x,9+y),color);
- draw_line(c,point(2+x,1+y),point(9+x,1+y),color);
- draw_line(c,point(4+x,0+y),point(7+x,0+y),color);
-
- color = rgb_pixel(255,255,255);
- draw_line(c,point(4+x,11+y),point(7+x,11+y),color);
- draw_line(c,point(2+x,10+y),point(9+x,10+y),color);
- draw_line(c,point(10+x,2+y),point(10+x,9+y),color);
- draw_line(c,point(11+x,4+y),point(11+x,7+y),color);
-
- color = rgb_pixel(64,64,64);
- draw_line(c,point(1+x,4+y),point(1+x,7+y),color);
- draw_line(c,point(4+x,1+y),point(7+x,1+y),color);
- draw_pixel(c,point(2+x,3+y),color);
- draw_pixel(c,point(3+x,2+y),color);
- draw_pixel(c,point(2+x,2+y),color);
- draw_pixel(c,point(2+x,8+y),color);
- draw_pixel(c,point(8+x,2+y),color);
- draw_pixel(c,point(9+x,2+y),color);
-
- color = rgb_pixel(212,208,200);
- draw_line(c,point(4+x,10+y),point(7+x,10+y),color);
- draw_line(c,point(10+x,4+y),point(10+x,7+y),color);
- draw_pixel(c,point(3+x,9+y),color);
- draw_pixel(c,point(9+x,3+y),color);
-
- if (enabled)
- {
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- }
- else
- {
- color.red = 128;
- color.green = 128;
- color.blue = 128;
- }
-
- mfont.draw_string(c,name_rect,name,color);
-
- if (is_checked)
- {
- draw_line(c,point(5+x,4+y),point(6+x,4+y),color);
- draw_line(c,point(4+x,5+y),point(7+x,5+y),color);
- draw_line(c,point(4+x,6+y),point(7+x,6+y),color);
- draw_line(c,point(5+x,7+y),point(6+x,7+y),color);
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle toggle_button_style_radio_button::
- get_min_size (
- const ustring& name,
- const font& mfont
- ) const
- {
- unsigned long width;
- unsigned long height;
- mfont.compute_size(name,width,height);
-
- if (height < 13)
- height = 13;
-
- return rectangle(width + 17 -1, height -1);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // scroll bar style stuff
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- long scroll_bar_style_default::
- get_slider_length (
- long total_length,
- long max_pos
- ) const
- {
- // if the length is too small then we have to smash up the arrow buttons
- // and hide the slider.
- if (total_length <= get_width()*2)
- {
- return 0;
- }
- else
- {
- double range = total_length - get_button_length(total_length, max_pos)*2;
-
- double scale_factor = 30.0/(max_pos + 30.0);
-
- if (scale_factor < 0.1)
- scale_factor = 0.1;
-
-
- double fraction = range/(max_pos + range)*scale_factor;
- double result = fraction * range;
- long res = static_cast<long>(result);
- if (res < 8)
- res = 8;
- return res;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- long scroll_bar_style_default::
- get_button_length (
- long total_length,
- long
- ) const
- {
- // if the length is too small then we have to smash up the arrow buttons
- // and hide the slider.
- if (total_length <= get_width()*2)
- {
- return total_length/2;
- }
- else
- {
- return get_width();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar_style_default::
- draw_scroll_bar_background (
- const canvas& c,
- const rectangle& rect,
- const bool ,
- const long ,
- const long ,
- const bool is_depressed
- ) const
- {
- if (is_depressed)
- draw_checkered(c, rect,rgb_pixel(0,0,0),rgb_pixel(43,47,55));
- else
- draw_checkered(c, rect,rgb_pixel(255,255,255),rgb_pixel(212,208,200));
- }
-
-// ----------------------------------------------------------------------------------------
-
- void scroll_bar_style_default::
- draw_scroll_bar_slider (
- const canvas& c,
- const rectangle& rect,
- const bool ,
- const long ,
- const long ,
- const bool
- ) const
- {
- fill_rect(c, rect, rgb_pixel(212,208,200));
- draw_button_up(c, rect);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // text_field styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- unsigned long text_field_style_default::
- get_padding (
- const font& mfont
- ) const
- {
- return mfont.height()-mfont.ascender();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field_style_default::
- draw_text_field (
- const canvas& c,
- const rectangle& rect,
- const rectangle& text_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const unsigned long cursor_x,
- const unsigned long text_pos,
- const rgb_pixel& text_color,
- const rgb_pixel& bg_color,
- const bool has_focus,
- const bool cursor_visible,
- const long highlight_start,
- const long highlight_end
- ) const
- {
- rectangle area = rect.intersect(c);
-
- if (enabled)
- {
- // first fill our area with the bg_color
- fill_rect(c, area,bg_color);
- }
- else
- {
- // first fill our area with gray
- fill_rect(c, area,rgb_pixel(212,208,200));
- }
-
-
- if (enabled)
- mfont.draw_string(c,text_rect,text,text_color,text_pos);
- else
- mfont.draw_string(c,text_rect,text,rgb_pixel(128,128,128),text_pos);
-
- // now draw the edge of the text_field
- draw_sunken_rectangle(c, rect);
-
- if (highlight_start <= highlight_end && enabled)
- {
- rectangle highlight_rect = text_rect;
- unsigned long left_pad = 0, right_pad = mfont.left_overflow();
-
- long i;
- for (i = text_pos; i <= highlight_end; ++i)
- {
- if (i == highlight_start)
- left_pad = right_pad;
-
- right_pad += mfont[text[i]].width();
- }
-
- highlight_rect.set_left(text_rect.left()+left_pad);
- highlight_rect.set_right(text_rect.left()+right_pad);
-
- // highlight the highlight_rect area
- highlight_rect = highlight_rect.intersect(c);
- for (long row = highlight_rect.top(); row <= highlight_rect.bottom(); ++row)
- {
- for (long col = highlight_rect.left(); col <= highlight_rect.right(); ++col)
- {
- canvas::pixel& pixel = c[row-c.top()][col-c.left()];
- if (pixel.red == 255 && pixel.green == 255 && pixel.blue == 255)
- {
- // this is a background (and white) pixel so set it to a dark
- // blueish color.
- pixel.red = 10;
- pixel.green = 36;
- pixel.blue = 106;
- }
- else
- {
- // this should be a pixel that is part of a letter so set it to white
- pixel.red = 255;
- pixel.green = 255;
- pixel.blue = 255;
- }
- }
- }
- }
-
- // now draw the cursor if we need to
- if (cursor_visible && has_focus && enabled)
- {
- const unsigned long top = rect.top()+3;
- const unsigned long bottom = rect.bottom()-3;
- draw_line(c, point(rect.left()+cursor_x,top),point(rect.left()+cursor_x,bottom));
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // text_box styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void text_box_style_default::
- draw_text_box (
- const canvas& c,
- const rectangle& display_rect,
- const rectangle& text_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const rectangle& cursor_rect,
- const rgb_pixel& text_color,
- const rgb_pixel& bg_color,
- const bool has_focus,
- const bool cursor_visible,
- const long highlight_start,
- const long highlight_end
- ) const
- {
- rectangle area = display_rect.intersect(c);
-
- if (enabled)
- {
- // first fill our area with the bg_color
- fill_rect(c, area,bg_color);
- }
- else
- {
- // first fill our area with gray
- fill_rect(c, area,rgb_pixel(212,208,200));
- }
-
-
- if (enabled)
- mfont.draw_string(c,text_rect,text,text_color, 0, ustring::npos, area);
- else
- mfont.draw_string(c,text_rect,text,rgb_pixel(128,128,128), 0, ustring::npos, area);
-
-
- // now draw the highlight if there is any
- if (highlight_start <= highlight_end && enabled)
- {
- const rectangle first_pos = mfont.compute_cursor_rect(text_rect, text, highlight_start);
- const rectangle last_pos = mfont.compute_cursor_rect(text_rect, text, highlight_end+1);
-
- const rgb_alpha_pixel color(10, 30, 106, 90);
-
- // if the highlighted text is all on one line
- if (first_pos.top() == last_pos.top())
- {
- fill_rect(c, (first_pos + last_pos).intersect(display_rect), color);
- }
- else
- {
- const rectangle min_boundary(display_rect.left()+4, display_rect.top()+4,
- display_rect.right()-4, display_rect.bottom()-4);
- const rectangle boundary( display_rect.intersect(text_rect) + min_boundary);
-
- rectangle first_row, last_row, middle_rows;
- first_row += first_pos;
- first_row += point(boundary.right(), first_pos.top());
- last_row += last_pos;
- last_row += point(boundary.left(), last_pos.bottom());
-
- middle_rows.left() = boundary.left();
- middle_rows.right() = boundary.right();
- middle_rows.top() = first_row.bottom()+1;
- middle_rows.bottom() = last_row.top()-1;
-
- fill_rect(c, first_row.intersect(display_rect), color);
- fill_rect(c, middle_rows, color);
- fill_rect(c, last_row.intersect(display_rect), color);
- }
- }
-
- // now draw the cursor if we need to
- if (cursor_visible && has_focus && enabled)
- {
- draw_line(c, point(cursor_rect.left(), cursor_rect.top()),point(cursor_rect.left(), cursor_rect.bottom()), 0, area);
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_WIDGETs_STYLE_CPP_
-
diff --git a/ml/dlib/dlib/gui_widgets/style.h b/ml/dlib/dlib/gui_widgets/style.h
deleted file mode 100644
index f31caee30..000000000
--- a/ml/dlib/dlib/gui_widgets/style.h
+++ /dev/null
@@ -1,825 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net), and Nils Labugt
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_WIDGETs_STYLE_
-#define DLIB_WIDGETs_STYLE_
-
-#include "../algs.h"
-#include "style_abstract.h"
-#include "../gui_core.h"
-#include "canvas_drawing.h"
-#include <string>
-#include <sstream>
-#include "../unicode.h"
-#include "../array2d.h"
-#include "../pixel.h"
-#include "fonts.h"
-
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // button styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class button_style
- {
- public:
-
- button_style()
- {
- }
-
- virtual ~button_style()
- {}
-
- virtual bool redraw_on_mouse_over (
- ) const { return false; }
-
- virtual rectangle get_invalidation_rect (
- const rectangle& rect
- ) const { return rect; }
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const = 0;
-
- virtual void draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed
- ) const = 0;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class button_style_default : public button_style
- {
- public:
- button_style_default () : padding(4), name_width(0) {}
-
- virtual void draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed
- ) const;
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const;
-
- private:
-
- // this is the minimum amount of padding that can separate the name from the
- // edge of the button
- const unsigned long padding;
- // this is the width of the name string
- mutable unsigned long name_width;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class button_style_toolbar1 : public button_style
- {
- public:
- button_style_toolbar1 () : padding(4), name_width(0) {}
-
- virtual void draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed
- ) const;
-
- virtual rectangle get_invalidation_rect (
- const rectangle& rect
- ) const
- {
- rectangle temp(rect);
- temp.left() -= 2;
- temp.top() -= 2;
- temp.right() += 2;
- temp.bottom() += 2;
- return temp;
- }
-
- virtual bool redraw_on_mouse_over (
- ) const { return true; }
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const;
-
- private:
-
- // this is the minimum amount of padding that can separate the name from the
- // edge of the button
- const unsigned long padding;
- // this is the width of the name string
- mutable unsigned long name_width;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class button_style_toolbar_icon1 : public button_style
- {
- public:
- template <typename image_type>
- button_style_toolbar_icon1 (const image_type& img_, unsigned long pad = 6) : padding(pad)
- {
- assign_image(img_mouseover,img_);
- make_images();
- }
-
- button_style_toolbar_icon1( const button_style_toolbar_icon1& item): button_style(item), padding(item.padding)
- {
- assign_image(img_mouseover, item.img_mouseover);
- assign_image(img_normal, item.img_normal);
- assign_image(img_disabled, item.img_disabled);
- }
-
- virtual void draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed
- ) const;
-
- virtual bool redraw_on_mouse_over (
- ) const { return true; }
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const;
-
- private:
-
- void make_images (
- )
- {
- // make the disabled image grayscale and make both non-mouseover images have weaker alpha channels
- img_disabled.set_size(img_mouseover.nr(), img_mouseover.nc());
- img_normal.set_size(img_mouseover.nr(), img_mouseover.nc());
-
- for (long r = 0; r < img_mouseover.nr(); ++r)
- {
- for (long c = 0; c < img_mouseover.nc(); ++c)
- {
- rgb_alpha_pixel p = img_mouseover[r][c];
- long avg = p.red;
- avg += p.green;
- avg += p.blue;
- avg /= 3;
-
- if (p.alpha > 40)
- p.alpha -= 40;
- else
- p.alpha = 0;
-
- img_normal[r][c] = p;
-
- if (p.alpha > 80)
- p.alpha -= 80;
- else
- p.alpha = 0;
-
- p.red = avg;
- p.green = avg;
- p.blue = avg;
- img_disabled[r][c] = p;
- }
- }
- }
-
- array2d<rgb_alpha_pixel> img_mouseover;
- array2d<rgb_alpha_pixel> img_normal;
- array2d<rgb_alpha_pixel> img_disabled;
-
- // this is the minimum amount of padding that can separate the name from the
- // edge of the button
- const unsigned long padding;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class button_style_arrow : public button_style
- {
-
- public:
-
- enum arrow_direction
- {
- UP,
- DOWN,
- LEFT,
- RIGHT
- };
-
- button_style_arrow (
- arrow_direction dir_
- ) : dir(dir_) {}
-
- virtual void draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed
- ) const;
-
- virtual rectangle get_min_size (
- const ustring& ,
- const font&
- ) const { return rectangle(); }
-
- private:
- arrow_direction dir;
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // toggle button styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class toggle_button_style
- {
- public:
-
- toggle_button_style()
- {
- }
-
- virtual ~toggle_button_style()
- {}
-
- virtual bool redraw_on_mouse_over (
- ) const { return false; }
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const = 0;
-
- virtual void draw_toggle_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed,
- const bool is_checked
- ) const = 0;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class toggle_button_style_default : public toggle_button_style
- {
- public:
- toggle_button_style_default () : padding(4), name_width(0) {}
-
- virtual void draw_toggle_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed,
- const bool is_checked
- ) const;
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const;
-
- private:
-
- // this is the minimum amount of padding that can separate the name from the
- // edge of the button
- const unsigned long padding;
- // this is the width of the name string
- mutable unsigned long name_width;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class toggle_button_style_check_box : public toggle_button_style
- {
- public:
- virtual void draw_toggle_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed,
- const bool is_checked
- ) const;
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class toggle_button_style_radio_button : public toggle_button_style
- {
- public:
- virtual void draw_toggle_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed,
- const bool is_checked
- ) const;
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const;
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // scroll_bar styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class scroll_bar_style
- {
- public:
-
- virtual ~scroll_bar_style() {}
-
- virtual bool redraw_on_mouse_over_slider (
- ) const { return false; }
-
- virtual long get_width (
- ) const = 0;
-
- virtual long get_slider_length (
- long total_length,
- long max_pos
- ) const = 0;
-
- virtual long get_button_length (
- long total_length,
- long max_pos
- ) const = 0;
-
- virtual void draw_scroll_bar_background (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const long lastx,
- const long lasty,
- const bool is_depressed
- ) const = 0;
-
- virtual void draw_scroll_bar_slider (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const long lastx,
- const long lasty,
- const bool is_being_dragged
- ) const = 0;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class scroll_bar_style_default : public scroll_bar_style
- {
- public:
- button_style_arrow get_up_button_style (
- ) const { return button_style_arrow(button_style_arrow::UP); }
-
- button_style_arrow get_down_button_style (
- ) const { return button_style_arrow(button_style_arrow::DOWN); }
-
- button_style_arrow get_left_button_style (
- ) const { return button_style_arrow(button_style_arrow::LEFT); }
-
- button_style_arrow get_right_button_style (
- ) const { return button_style_arrow(button_style_arrow::RIGHT); }
-
- virtual long get_width (
- ) const { return 16; }
-
- virtual long get_slider_length (
- long total_length,
- long max_pos
- ) const;
-
- virtual long get_button_length (
- long total_length,
- long max_pos
- ) const;
-
- virtual void draw_scroll_bar_background (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const long lastx,
- const long lasty,
- const bool is_depressed
- ) const;
-
- virtual void draw_scroll_bar_slider (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const long lastx,
- const long lasty,
- const bool is_being_dragged
- ) const;
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // scrollable_region styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class scrollable_region_style
- {
- public:
-
- virtual ~scrollable_region_style() {}
-
- virtual long get_border_size (
- ) const = 0;
-
- virtual void draw_scrollable_region_border (
- const canvas& c,
- const rectangle& rect,
- const bool enabled
- ) const = 0;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class scrollable_region_style_default : public scrollable_region_style
- {
- public:
- scroll_bar_style_default get_horizontal_scroll_bar_style (
- ) const { return scroll_bar_style_default(); }
-
- scroll_bar_style_default get_vertical_scroll_bar_style (
- ) const { return scroll_bar_style_default(); }
-
- virtual long get_border_size (
- ) const { return 2; }
-
- virtual void draw_scrollable_region_border (
- const canvas& c,
- const rectangle& rect,
- const bool
- ) const { draw_sunken_rectangle(c,rect); }
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // list_box styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class list_box_style
- {
- public:
-
- virtual ~list_box_style() {}
-
- virtual void draw_list_box_background (
- const canvas& c,
- const rectangle& display_rect,
- const bool enabled
- ) const = 0;
-
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const std::string& text,
- const bool is_selected
- ) const = 0;
-
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const std::wstring& text,
- const bool is_selected
- ) const = 0;
-
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const bool is_selected
- ) const = 0;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class list_box_style_default : public list_box_style
- {
- public:
- scrollable_region_style_default get_scrollable_region_style (
- ) const { return scrollable_region_style_default(); }
-
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const std::string& text,
- const bool is_selected
- ) const { draw_list_box_item_template(c,rect,display_rect, enabled, mfont, text, is_selected); }
-
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const std::wstring& text,
- const bool is_selected
- ) const { draw_list_box_item_template(c,rect,display_rect, enabled, mfont, text, is_selected); }
-
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const bool is_selected
- ) const { draw_list_box_item_template(c,rect,display_rect, enabled, mfont, text, is_selected); }
-
- template <typename string_type>
- void draw_list_box_item_template (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const string_type& text,
- const bool is_selected
- ) const
- {
- if (is_selected)
- {
- if (enabled)
- fill_rect_with_vertical_gradient(c,rect,rgb_pixel(110,160,255), rgb_pixel(100,130,250),display_rect);
- else
- fill_rect_with_vertical_gradient(c,rect,rgb_pixel(140,190,255), rgb_pixel(130,160,250),display_rect);
- }
-
- if (enabled)
- mfont.draw_string(c,rect,text,rgb_pixel(0,0,0),0,std::string::npos,display_rect);
- else
- mfont.draw_string(c,rect,text,rgb_pixel(128,128,128),0,std::string::npos,display_rect);
- }
-
- virtual void draw_list_box_background (
- const canvas& c,
- const rectangle& display_rect,
- const bool enabled
- ) const
- {
- if (enabled)
- {
- // first fill our area with white
- fill_rect(c, display_rect,rgb_pixel(255,255,255));
- }
- else
- {
- // first fill our area with gray
- fill_rect(c, display_rect,rgb_pixel(212,208,200));
- }
- }
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // text_box styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_box_style
- {
- public:
-
- text_box_style()
- {
- }
-
- virtual ~text_box_style()
- {}
-
- virtual unsigned long get_padding (
- const font& mfont
- ) const = 0;
-
- virtual void draw_text_box (
- const canvas& c,
- const rectangle& display_rect,
- const rectangle& text_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const rectangle& cursor_rect,
- const rgb_pixel& text_color,
- const rgb_pixel& bg_color,
- const bool has_focus,
- const bool cursor_visible,
- const long highlight_start,
- const long highlight_end
- ) const = 0;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class text_box_style_default : public text_box_style
- {
- public:
-
- text_box_style_default()
- {
- }
-
- scrollable_region_style_default get_scrollable_region_style (
- ) const { return scrollable_region_style_default(); }
-
- virtual ~text_box_style_default()
- {}
-
- virtual unsigned long get_padding (
- const font&
- ) const { return 1; }
-
- virtual void draw_text_box (
- const canvas& c,
- const rectangle& display_rect,
- const rectangle& text_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const rectangle& cursor_rect,
- const rgb_pixel& text_color,
- const rgb_pixel& bg_color,
- const bool has_focus,
- const bool cursor_visible,
- const long highlight_start,
- const long highlight_end
- ) const;
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // text_field styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_field_style
- {
- public:
-
- text_field_style()
- {
- }
-
- virtual ~text_field_style()
- {}
-
- virtual unsigned long get_padding (
- const font& mfont
- ) const = 0;
-
- virtual void draw_text_field (
- const canvas& c,
- const rectangle& rect,
- const rectangle& text_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const unsigned long cursor_x,
- const unsigned long text_pos,
- const rgb_pixel& text_color,
- const rgb_pixel& bg_color,
- const bool has_focus,
- const bool cursor_visible,
- const long highlight_start,
- const long highlight_end
- ) const = 0;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class text_field_style_default : public text_field_style
- {
- public:
-
- text_field_style_default()
- {
- }
-
- virtual ~text_field_style_default()
- {}
-
- virtual unsigned long get_padding (
- const font& mfont
- ) const;
-
- virtual void draw_text_field (
- const canvas& c,
- const rectangle& rect,
- const rectangle& text_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const unsigned long cursor_x,
- const unsigned long text_pos,
- const rgb_pixel& text_color,
- const rgb_pixel& bg_color,
- const bool has_focus,
- const bool cursor_visible,
- const long highlight_start,
- const long highlight_end
- ) const;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "style.cpp"
-#endif
-
-#endif // DLIB_WIDGETs_STYLE_
-
-
diff --git a/ml/dlib/dlib/gui_widgets/style_abstract.h b/ml/dlib/dlib/gui_widgets/style_abstract.h
deleted file mode 100644
index e4d3245df..000000000
--- a/ml/dlib/dlib/gui_widgets/style_abstract.h
+++ /dev/null
@@ -1,777 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net), and Nils Labugt
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_WIDGETs_STYLE_ABSTRACT_
-#ifdef DLIB_WIDGETs_STYLE_ABSTRACT_
-
-#include "../algs.h"
-#include "../gui_core.h"
-#include "widgets_abstract.h"
-#include "../unicode/unicode_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // button styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class button_style
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an abstract class that defines the interface a
- button style object must implement.
-
- Note that derived classes must be copyable via
- their copy constructors.
- !*/
-
- public:
-
- virtual ~button_style() {}
-
- virtual bool redraw_on_mouse_over (
- ) const { return false; }
- /*!
- ensures
- - if (this style draws buttons differently when a mouse is over them) then
- - returns true
- - else
- - returns false
- !*/
-
- virtual rectangle get_invalidation_rect (
- const rectangle& rect
- ) const { return rect; }
- /*!
- requires
- - the mutex drawable::m is locked
- - rect == the get_rect() that defines where the button is
- ensures
- - returns a rectangle that should be invalidated whenever a button
- needs to redraw itself. (e.g. If you wanted your button style to
- draw outside the button then you could return a larger rectangle)
- !*/
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- ensures
- - returns a rectangle that represents the minimum size of the button
- given the name and font.
- !*/
-
- virtual void draw_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - rect, enabled, mfont, lastx, and lasty are the variables
- defined in the protected section of the drawable class.
- - name == the name of the button to be drawn
- - is_depressed == true if the button is to be drawn in a depressed state
- ensures
- - draws the button on the canvas c at the location given by rect.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class button_style_default : public button_style
- {
- /*!
- This is the default style for button objects. It will cause
- a button to appear as the simple MS Windows 2000 button style.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class button_style_toolbar1 : public button_style
- {
- /*!
- This draws a simple toolbar style button that displays its name in the
- middle of itself. When the mouse moves over it it will light up.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class button_style_toolbar_icon1 : public button_style
- {
- /*!
- This draws a simple toolbar style button that displays an image in the
- middle of itself. When the mouse moves over it it will light up.
- !*/
- template <typename image_type>
- button_style_toolbar_icon1 (
- const image_type& img,
- unsigned long border_size = 6
- );
- /*!
- requires
- - image_type == an implementation of array2d/array2d_kernel_abstract.h
- - pixel_traits<typename image_type::type> is defined
- ensures
- - displays image img in the middle of the button
- - the distance between the edge of the button and the image
- will be border_size pixels
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class button_style_arrow : public button_style
- {
- public:
- /*!
- This draws a simple button with an arrow in it
- !*/
-
- enum arrow_direction
- {
- UP,
- DOWN,
- LEFT,
- RIGHT
- };
-
- button_style_arrow (
- arrow_direction dir
- );
- /*!
- ensures
- - the arrow in the button will point in the given direction
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // toggle button styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class toggle_button_style
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an abstract class that defines the interface a
- toggle button style object must implement.
-
- Note that derived classes must be copyable via
- their copy constructors.
- !*/
-
- public:
-
- virtual ~toggle_button_style() {}
-
- virtual bool redraw_on_mouse_over (
- ) const { return false; }
- /*!
- ensures
- - if (this style draws buttons differently when a mouse is over them) then
- - returns true
- - else
- - returns false
- !*/
-
- virtual rectangle get_min_size (
- const ustring& name,
- const font& mfont
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- ensures
- - returns a rectangle that represents the minimum size of the button
- given the name and font.
- !*/
-
- virtual void draw_toggle_button (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const font& mfont,
- const long lastx,
- const long lasty,
- const ustring& name,
- const bool is_depressed,
- const bool is_checked
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - rect, enabled, mfont, lastx, and lasty are the variables
- defined in the protected section of the drawable class.
- - name == the name of the button to be drawn
- - is_depressed == true if the button is to be drawn in a depressed state
- - is_checked == true if the toggle_button is in the checked state
- ensures
- - draws the button on the canvas c at the location given by rect.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class toggle_button_style_default : public toggle_button_style
- {
- /*!
- This is the default style for toggle_button objects. It will cause
- a button to appear as the simple MS Windows 2000 button style.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class toggle_button_style_check_box : public toggle_button_style
- {
- /*!
- This draws a simple check box style toggle button that displays its
- name to the right of a check box.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class toggle_button_style_radio_button : public toggle_button_style
- {
- /*!
- This draws a simple radio button style toggle button that displays its
- name to the right of a circular radio button.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // scroll_bar styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class scroll_bar_style
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an abstract class that defines the interface a
- scroll_bar style object must implement.
-
- Note that derived classes must be copyable via
- their copy constructors.
-
- There are three parts of a scroll bar, the slider, the background,
- and the two buttons on its ends. The "slider" is the thing that you
- drag around on the scroll bar and the "background" is the part
- in between the slider and the buttons on the ends.
- !*/
-
- public:
-
- virtual ~scroll_bar_style() {}
-
- virtual bool redraw_on_mouse_over_slider (
- ) const { return false; }
- /*!
- ensures
- - if (this style draws a scroll_bar's slider differently when a mouse is over it
- or it is being dragged) then
- - returns true
- - else
- - returns false
- !*/
-
- virtual long get_width (
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- ensures
- - returns the width in pixels of the scroll bar
- !*/
-
- virtual long get_slider_length (
- long total_length,
- long max_pos
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - total_length == the total length in pixels of the scroll bar
- - max_pos == the value of scroll_bar::max_slider_pos() for this
- scroll bar
- ensures
- - returns the length in pixels of the scroll bar's slider
- !*/
-
- virtual long get_button_length (
- long total_length,
- long max_pos
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - total_length == the total length in pixels of the scroll bar
- - max_pos == the value of scroll_bar::max_slider_pos() for this
- scroll bar
- ensures
- - returns the length in pixels of each of the scroll bar's
- buttons
- !*/
-
- virtual void draw_scroll_bar_background (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const long lastx,
- const long lasty,
- const bool is_depressed
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - rect, enabled, lastx, and lasty are the variables
- defined in the protected section of the drawable class.
- - is_depressed == true if the background area of the scroll_bar is to
- be drawn in a depressed state (because the user is clicking on it)
- ensures
- - draws the background part of the scroll_bar on the canvas c at the
- location given by rect.
- !*/
-
- virtual void draw_scroll_bar_slider (
- const canvas& c,
- const rectangle& rect,
- const bool enabled,
- const long lastx,
- const long lasty,
- const bool is_being_dragged
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - rect, enabled, lastx, and lasty are the variables
- defined in the protected section of the drawable class
- - is_being_dragged == true if the user is dragging the slider
- ensures
- - draws the slider part of the scroll_bar on the canvas c at the
- location given by rect.
- !*/
-
- button_style_type get_up_button_style (
- ) const;
- /*!
- ensures
- - returns the type of button_style to use for a button on the
- top side of a vertical scroll bar.
- !*/
-
- button_style_type get_down_button_style (
- ) const;
- /*!
- ensures
- - returns the type of button_style to use for a button on the
- bottom side of a vertical scroll bar.
- !*/
-
- button_style_type get_left_button_style (
- ) const;
- /*!
- ensures
- - returns the type of button_style to use for a button on the
- left side of a horizontal scroll bar.
- !*/
-
- button_style_type get_right_button_style (
- ) const;
- /*!
- ensures
- - returns the type of button_style to use for a button on the
- right side of a horizontal scroll bar.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class scroll_bar_style_default : public scroll_bar_style
- {
- /*!
- This is the default style for scroll_bar objects. It will cause
- a scroll_bar to appear as the simple MS Windows 2000 scroll_bar style.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // scrollable_region (and zoomable_region) styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class scrollable_region_style
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an abstract class that defines the interface a
- scrollable_region and zoomable_region style object must implement.
-
- Note that derived classes must be copyable via
- their copy constructors.
- !*/
- public:
-
- virtual ~scrollable_region_style() {}
-
- virtual long get_border_size (
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- ensures
- - returns the size of the border region in pixels
- !*/
-
- virtual void draw_scrollable_region_border (
- const canvas& c,
- const rectangle& rect,
- const bool enabled
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - rect and enabled are the variables defined in the protected section
- of the drawable class.
- ensures
- - draws the border part of a scrollable_region on the canvas c at the
- location given by rect.
- !*/
-
- scroll_bar_style_type get_horizontal_scroll_bar_style (
- ) const;
- /*!
- ensures
- - returns the style of scroll_bar to use for the
- horizontal scroll_bar in this widget.
- !*/
-
- scroll_bar_style_type get_vertical_scroll_bar_style (
- ) const;
- /*!
- ensures
- - returns the style of scroll_bar to use for the
- vertical scroll_bar in this widget.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class scrollable_region_style_default : public scrollable_region_style
- {
- public:
- /*!
- This is the default style for scrollable_region and zoomable_region objects.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // text_box styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_box_style
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an abstract class that defines the interface a
- text_box style object must implement.
-
- Note that derived classes must be copyable via
- their copy constructors.
- !*/
- public:
-
- virtual ~text_field_style() {}
-
- scrollable_region_style_type get_scrollable_region_style (
- ) const;
- /*!
- ensures
- - returns the style of scrollable_region to use for the
- text_box.
- !*/
-
- virtual unsigned long get_padding (
- const font& mfont
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- ensures
- - returns the number of pixels that separate the text in the text_box
- from the edge of the text_box widget itself.
- !*/
-
- virtual void draw_text_box (
- const canvas& c,
- const rectangle& display_rect,
- const rectangle& text_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const rectangle& cursor_rect,
- const rgb_pixel& text_color,
- const rgb_pixel& bg_color,
- const bool has_focus,
- const bool cursor_visible,
- const long highlight_start,
- const long highlight_end
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - enabled and mfont are the variables defined in the protected section
- - text_rect == the rectangle in which we should draw the given text
- of the drawable class.
- - display_rect == the rectangle returned by scrollable_region::display_rect()
- - text == the current text in the text_box
- - cursor_rect == A rectangle of width 1 that represents the current
- position of the cursor on the screen.
- - text_color == the color of the text to be drawn
- - bg_color == the background color of the text field
- - has_focus == true if this text field has keyboard input focus
- - cursor_visible == true if the cursor should be drawn
- - if (highlight_start <= highlight_end) then
- - text[highlight_start] though text[highlight_end] should be
- highlighted
- ensures
- - draws the text_box on the canvas c at the location given by text_rect.
- (Note that the scroll bars and borders are drawn by the scrollable_region
- and therefore the style returned by get_scrollable_region_style()
- controls how those appear)
- - doesn't draw anything outside display_rect
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- class text_box_style_default : public text_box_style
- {
- public:
- /*!
- This is the default style for text_box objects.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // list_box styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class list_box_style
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an abstract class that defines the interface a
- list_box style object must implement.
-
- Note that derived classes must be copyable via
- their copy constructors.
- !*/
- public:
-
- virtual ~list_box_style() {}
-
- virtual void draw_list_box_background (
- const canvas& c,
- const rectangle& display_rect,
- const bool enabled
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - display_rect == the display_rect for the list_box. This is the area
- in which list box items are drawn (see display_rect in the scrollable_region
- widget for more info)
- - enabled == true if the list box is enabled
- ensures
- - draws the background of a list box on the canvas c at the location given
- by display_rect.
- !*/
-
- scrollable_region_style_type get_scrollable_region_style (
- ) const;
- /*!
- ensures
- - returns the style of scrollable_region to use for the
- list_box.
- !*/
-
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const std::string& text,
- const bool is_selected
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - rect == the rectangle that defines where on the screen this list box item is.
- - display_rect == the display_rect for the list_box. This is the area
- in which list box items are drawn (see display_rect in the scrollable_region
- widget for more info)
- - mfont == the font to use to draw the list box item
- - text == the text of the list box item to be drawn
- - enabled == true if the list box is enabled
- - is_selected == true if the item is to be drawn in a selected state
- ensures
- - draws the list box item on the canvas c at the location given by rect.
- !*/
-
- // wide character overloads
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const std::wstring& text,
- const bool is_selected
- ) const = 0;
-
- virtual void draw_list_box_item (
- const canvas& c,
- const rectangle& rect,
- const rectangle& display_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const bool is_selected
- ) const = 0;
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class list_box_style_default : public list_box_style
- {
- public:
- /*!
- This is the default style for list_box objects.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // text_field styles
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_field_style
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is an abstract class that defines the interface a
- text_field style object must implement.
-
- Note that derived classes must be copyable via
- their copy constructors.
- !*/
- public:
-
- virtual ~text_field_style() {}
-
- virtual unsigned long get_padding (
- const font& mfont
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- ensures
- - returns the number of pixels that separate the text in the text_field
- from the edge of the text_field widget itself.
- !*/
-
- virtual void draw_text_field (
- const canvas& c,
- const rectangle& rect,
- const rectangle& text_rect,
- const bool enabled,
- const font& mfont,
- const ustring& text,
- const unsigned long cursor_x,
- const unsigned long text_pos,
- const rgb_pixel& text_color,
- const rgb_pixel& bg_color,
- const bool has_focus,
- const bool cursor_visible,
- const long highlight_start,
- const long highlight_end
- ) const = 0;
- /*!
- requires
- - the mutex drawable::m is locked
- - c == the canvas to draw on
- - rect, enabled, and mfont are the variables defined in the protected section
- of the drawable class.
- - text == the current text in the text_field
- - text_rect == the rectangle in which we should draw the given text
- - cursor_x == the x coordinate of the cursor relative to the left side
- of rect. i.e. the number of pixels that separate the cursor from the
- left side of the text_field.
- - text_pos == the index of the first letter in text that appears in
- this text field.
- - text_color == the color of the text to be drawn
- - bg_color == the background color of the text field
- - has_focus == true if this text field has keyboard input focus
- - cursor_visible == true if the cursor should be drawn
- - if (highlight_start <= highlight_end) then
- - text[highlight_start] though text[highlight_end] should be
- highlighted
- ensures
- - draws the text_field on the canvas c at the location given by rect.
- !*/
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- class text_field_style_default : public text_field_style
- {
- public:
- /*!
- This is the default style for text_field objects.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_WIDGETs_STYLE_ABSTRACT_
-
-
-
diff --git a/ml/dlib/dlib/gui_widgets/widgets.cpp b/ml/dlib/dlib/gui_widgets/widgets.cpp
deleted file mode 100644
index c460d946d..000000000
--- a/ml/dlib/dlib/gui_widgets/widgets.cpp
+++ /dev/null
@@ -1,7341 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_WIDGETs_CPP_
-#define DLIB_WIDGETs_CPP_
-
-#include <algorithm>
-#include <memory>
-
-#include "widgets.h"
-#include "../string.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // toggle_button object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- rectangle min_rect = style->get_min_size(name_,*mfont);
- // only change the size if it isn't going to be too small to fit the name
- if (height >= min_rect.height() &&
- width >= min_rect.width())
- {
- rectangle old(rect);
- rect = resize_rect(rect,width,height);
- parent.invalidate_rectangle(rect+old);
- btn_tooltip.set_size(width,height);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- set_checked (
- )
- {
- auto_mutex M(m);
- checked = true;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- set_unchecked (
- )
- {
- auto_mutex M(m);
- checked = false;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool toggle_button::
- is_checked (
- ) const
- {
- auto_mutex M(m);
- return checked;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- show (
- )
- {
- button_action::show();
- btn_tooltip.show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- hide (
- )
- {
- button_action::hide();
- btn_tooltip.hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- enable (
- )
- {
- button_action::enable();
- btn_tooltip.enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- disable (
- )
- {
- button_action::disable();
- btn_tooltip.disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- set_tooltip_text (
- const std::string& text
- )
- {
- btn_tooltip.set_text(text);
- }
-
- void toggle_button::
- set_tooltip_text (
- const std::wstring& text
- )
- {
- btn_tooltip.set_text(text);
- }
-
- void toggle_button::
- set_tooltip_text (
- const dlib::ustring& text
- )
- {
- btn_tooltip.set_text(text);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string toggle_button::
- tooltip_text (
- ) const
- {
- return btn_tooltip.text();
- }
-
- const std::wstring toggle_button::
- tooltip_wtext (
- ) const
- {
- return btn_tooltip.wtext();
- }
-
- const dlib::ustring toggle_button::
- tooltip_utext (
- ) const
- {
- return btn_tooltip.utext();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- set_name(name_);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- set_pos (
- long x,
- long y
- )
- {
- auto_mutex M(m);
- button_action::set_pos(x,y);
- btn_tooltip.set_pos(x,y);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- set_name (
- const std::string& name
- )
- {
- set_name(convert_mbstring_to_wstring(name));
- }
-
- void toggle_button::
- set_name (
- const std::wstring& name
- )
- {
- set_name(convert_wstring_to_utf32(name));
- }
-
- void toggle_button::
- set_name (
- const dlib::ustring& name
- )
- {
- auto_mutex M(m);
- name_ = name;
- // do this to get rid of any reference counting that may be present in
- // the std::string implementation.
- name_[0] = name_[0];
-
- rectangle old(rect);
- rect = move_rect(style->get_min_size(name,*mfont),rect.left(),rect.top());
- btn_tooltip.set_size(rect.width(),rect.height());
-
- parent.invalidate_rectangle(rect+old);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string toggle_button::
- name (
- ) const
- {
- return convert_wstring_to_mbstring(wname());
- }
-
- const std::wstring toggle_button::
- wname (
- ) const
- {
- return convert_utf32_to_wstring(uname());
- }
-
- const dlib::ustring toggle_button::
- uname (
- ) const
- {
- auto_mutex M(m);
- dlib::ustring temp = name_;
- // do this to get rid of any reference counting that may be present in
- // the std::string implementation.
- temp[0] = name_[0];
- return temp;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void toggle_button::
- on_button_up (
- bool mouse_over
- )
- {
- if (mouse_over)
- {
- checked = !checked;
- // this is a valid toggle_button click
- if (event_handler.is_set())
- event_handler();
- else if (event_handler_self.is_set())
- event_handler_self(*this);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // label object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void label::
- draw (
- const canvas& c
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty() || text_.size() == 0)
- return;
-
- using namespace std;
- unsigned char r = text_color_.red;
- unsigned char g = text_color_.green;
- unsigned char b = text_color_.blue;
- if (!enabled)
- {
- r = 128;
- g = 128;
- b = 128;
- }
-
- rectangle text_rect(rect);
-
- string::size_type first, last;
- first = 0;
- last = text_.find_first_of('\n');
- mfont->draw_string(c,text_rect,text_,rgb_pixel(r,g,b),first,last);
-
- while (last != string::npos)
- {
- first = last+1;
- last = text_.find_first_of('\n',first);
- text_rect.set_top(text_rect.top()+mfont->height());
- mfont->draw_string(c,text_rect,text_,rgb_pixel(r,g,b),first,last);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void label::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- set_text(text_);
- }
-
-// ----------------------------------------------------------------------------------------
-
-
- void label::
- set_text (
- const std::string& text
- )
- {
- set_text(convert_mbstring_to_wstring(text));
- }
-
- void label::
- set_text (
- const std::wstring& text
- )
- {
- set_text(convert_wstring_to_utf32(text));
- }
-
- void label::
- set_text (
- const dlib::ustring& text
- )
- {
- using namespace std;
- auto_mutex M(m);
- text_ = text;
- // do this to get rid of any reference counting that may be present in
- // the std::string implementation.
- text_[0] = text[0];
-
- rectangle old(rect);
-
- unsigned long width;
- unsigned long height;
- mfont->compute_size(text,width,height);
-
- rect.set_right(rect.left() + width - 1);
- rect.set_bottom(rect.top() + height - 1);
-
- parent.invalidate_rectangle(rect+old);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string label::
- text (
- ) const
- {
- return convert_wstring_to_mbstring(wtext());
- }
-
- const std::wstring label::
- wtext (
- ) const
- {
- return convert_utf32_to_wstring(utext());
- }
-
- const dlib::ustring label::
- utext (
- ) const
- {
- auto_mutex M(m);
- dlib::ustring temp = text_;
- // do this to get rid of any reference counting that may be present in
- // the std::string implementation.
- temp[0] = text_[0];
- return temp;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void label::
- set_text_color (
- const rgb_pixel color
- )
- {
- m.lock();
- text_color_ = color;
- parent.invalidate_rectangle(rect);
- m.unlock();
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rgb_pixel label::
- text_color (
- ) const
- {
- auto_mutex M(m);
- return text_color_;
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // text_field object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- rectangle text_field::
- get_text_rect (
- ) const
- {
- // figure out where the text string should appear
- unsigned long vertical_pad = (rect.height() - mfont->height())/2+1;
-
- rectangle text_rect;
- text_rect.set_left(rect.left()+style->get_padding(*mfont));
- text_rect.set_top(rect.top()+vertical_pad);
- text_rect.set_right(rect.right()-style->get_padding(*mfont));
- text_rect.set_bottom(text_rect.top()+mfont->height()-1);
- return text_rect;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- enable (
- )
- {
- drawable::enable();
- right_click_menu.enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- give_input_focus (
- )
- {
- auto_mutex M(m);
- has_focus = true;
- cursor_visible = true;
- parent.invalidate_rectangle(rect);
- t.start();
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool text_field::
- has_input_focus (
- ) const
- {
- auto_mutex M(m);
- return has_focus;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- select_all_text (
- )
- {
- auto_mutex M(m);
- on_select_all();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_cut (
- )
- {
- on_copy();
- on_delete_selected();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_copy (
- )
- {
- if (highlight_start <= highlight_end)
- {
- put_on_clipboard(text_.substr(highlight_start, highlight_end-highlight_start+1));
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_paste (
- )
- {
- ustring temp_str;
- get_from_clipboard(temp_str);
-
- // If this is a multi line string then just take the first line.
- ustring::size_type pos = temp_str.find_first_of('\n');
- if (pos != ustring::npos)
- {
- temp_str = temp_str.substr(0,pos);
- }
-
- if (highlight_start <= highlight_end)
- {
- text_ = text_.substr(0,highlight_start) + temp_str +
- text_.substr(highlight_end+1,text_.size()-highlight_end-1);
- move_cursor(highlight_start+temp_str.size());
- highlight_start = 0;
- highlight_end = -1;
- parent.invalidate_rectangle(rect);
- on_no_text_selected();
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- else
- {
- text_ = text_.substr(0,cursor_pos) + temp_str +
- text_.substr(cursor_pos,text_.size()-cursor_pos);
- move_cursor(cursor_pos+temp_str.size());
-
- // send out the text modified event
- if (temp_str.size() != 0 && text_modified_handler.is_set())
- text_modified_handler();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_select_all (
- )
- {
- move_cursor(static_cast<long>(text_.size()));
- highlight_start = 0;
- highlight_end = static_cast<long>(text_.size()-1);
- if (highlight_start <= highlight_end)
- on_text_is_selected();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_delete_selected (
- )
- {
- if (highlight_start <= highlight_end)
- {
- text_ = text_.erase(highlight_start,highlight_end-highlight_start+1);
- move_cursor(highlight_start);
- highlight_start = 0;
- highlight_end = -1;
-
- on_no_text_selected();
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
-
- parent.invalidate_rectangle(rect);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_text_is_selected (
- )
- {
- right_click_menu.menu().enable_menu_item(0);
- right_click_menu.menu().enable_menu_item(1);
- right_click_menu.menu().enable_menu_item(3);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_no_text_selected (
- )
- {
- right_click_menu.menu().disable_menu_item(0);
- right_click_menu.menu().disable_menu_item(1);
- right_click_menu.menu().disable_menu_item(3);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- show (
- )
- {
- drawable::show();
- right_click_menu.show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- disable (
- )
- {
- auto_mutex M(m);
- drawable::disable();
- t.stop();
- has_focus = false;
- cursor_visible = false;
- right_click_menu.disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- hide (
- )
- {
- auto_mutex M(m);
- drawable::hide();
- t.stop();
- has_focus = false;
- cursor_visible = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- // adjust the height of this text field so that it is appropriate for the current
- // font size
- rect.set_bottom(rect.top() + mfont->height()+ (style->get_padding(*mfont))*2);
- set_text(text_);
- right_click_menu.set_rect(get_text_rect());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- draw (
- const canvas& c
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- style->draw_text_field(c,rect,get_text_rect(), enabled, *mfont, text_, cursor_x, text_pos,
- text_color_, bg_color_, has_focus, cursor_visible, highlight_start,
- highlight_end);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- set_text (
- const std::string& text
- )
- {
- set_text(convert_mbstring_to_wstring(text));
- }
-
- void text_field::
- set_text (
- const std::wstring& text
- )
- {
- set_text(convert_wstring_to_utf32(text));
- }
-
- void text_field::
- set_text (
- const dlib::ustring& text
- )
- {
- DLIB_ASSERT ( text.find_first_of('\n') == std::string::npos ,
- "\tvoid text_field::set_text()"
- << "\n\ttext: " << narrow(text) );
- auto_mutex M(m);
- // do this to get rid of any reference counting that may be present in
- // the std::string implementation.
- text_ = text.c_str();
-
- move_cursor(0);
-
- highlight_start = 0;
- highlight_end = -1;
-
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string text_field::
- text (
- ) const
- {
- std::string temp = convert_wstring_to_mbstring(wtext());
- return temp;
- }
-
- const std::wstring text_field::
- wtext (
- ) const
- {
- std::wstring temp = convert_utf32_to_wstring(utext());
- return temp;
- }
-
- const dlib::ustring text_field::
- utext (
- ) const
- {
- auto_mutex M(m);
- // do this to get rid of any reference counting that may be present in
- // the dlib::ustring implementation.
- dlib::ustring temp = text_.c_str();
- return temp;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- set_width (
- unsigned long width
- )
- {
- auto_mutex M(m);
- if (width < style->get_padding(*mfont)*2)
- return;
-
- rectangle old(rect);
-
- rect.set_right(rect.left() + width - 1);
-
- right_click_menu.set_rect(get_text_rect());
- parent.invalidate_rectangle(rect+old);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- set_pos (
- long x,
- long y
- )
- {
- drawable::set_pos(x,y);
- right_click_menu.set_rect(get_text_rect());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- set_background_color (
- const rgb_pixel color
- )
- {
- auto_mutex M(m);
- bg_color_ = color;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rgb_pixel text_field::
- background_color (
- ) const
- {
- auto_mutex M(m);
- return bg_color_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- set_text_color (
- const rgb_pixel color
- )
- {
- auto_mutex M(m);
- text_color_ = color;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rgb_pixel text_field::
- text_color (
- ) const
- {
- auto_mutex M(m);
- return text_color_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- if (!enabled || hidden || !has_focus)
- {
- return;
- }
-
- if (state & base_window::LEFT)
- {
- if (highlight_start <= highlight_end)
- {
- if (highlight_start == cursor_pos)
- shift_pos = highlight_end + 1;
- else
- shift_pos = highlight_start;
- }
-
- unsigned long new_pos = mfont->compute_cursor_pos(get_text_rect(),text_,x,y,text_pos);
- if (static_cast<long>(new_pos) != cursor_pos)
- {
- move_cursor(new_pos);
- parent.invalidate_rectangle(rect);
- }
- }
- else if (shift_pos != -1)
- {
- shift_pos = -1;
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_mouse_up (
- unsigned long btn,
- unsigned long,
- long ,
- long
- )
- {
- if (!enabled || hidden)
- return;
-
- if (btn == base_window::LEFT)
- shift_pos = -1;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool double_clicked
- )
- {
- using namespace std;
- if (!enabled || hidden || btn != (unsigned long)base_window::LEFT)
- return;
-
- if (rect.contains(x,y))
- {
- has_focus = true;
- cursor_visible = true;
- parent.invalidate_rectangle(rect);
- t.start();
-
- if (double_clicked)
- {
- // highlight the double clicked word
- string::size_type first, last;
- const ustring ustr = convert_utf8_to_utf32(std::string(" \t\n"));
- first = text_.substr(0,cursor_pos).find_last_of(ustr.c_str());
- last = text_.find_first_of(ustr.c_str(),cursor_pos);
- long f = static_cast<long>(first);
- long l = static_cast<long>(last);
- if (first == string::npos)
- f = -1;
- if (last == string::npos)
- l = static_cast<long>(text_.size());
-
- ++f;
- --l;
-
- move_cursor(l+1);
- highlight_start = f;
- highlight_end = l;
- on_text_is_selected();
- }
- else
- {
- if (state & base_window::SHIFT)
- {
- if (highlight_start <= highlight_end)
- {
- if (highlight_start == cursor_pos)
- shift_pos = highlight_end + 1;
- else
- shift_pos = highlight_start;
- }
- else
- {
- shift_pos = cursor_pos;
- }
- }
-
- bool at_end = false;
- if (cursor_pos == 0 || cursor_pos == static_cast<long>(text_.size()))
- at_end = true;
- const long old_pos = cursor_pos;
-
- unsigned long new_pos = mfont->compute_cursor_pos(get_text_rect(),text_,x,y,text_pos);
- if (static_cast<long>(new_pos) != cursor_pos)
- {
- move_cursor(new_pos);
- parent.invalidate_rectangle(rect);
- }
- shift_pos = cursor_pos;
-
- if (at_end && cursor_pos == old_pos)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
-
- }
- else if (has_focus)
- {
- t.stop();
- has_focus = false;
- cursor_visible = false;
- shift_pos = -1;
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
-
- if (focus_lost_handler.is_set())
- focus_lost_handler();
- parent.invalidate_rectangle(rect);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- )
- {
- // If the right click menu is up then we don't want to do anything with
- // the keyboard ourselves. Let the popup menu use the keyboard for now.
- if (right_click_menu.popup_menu_visible())
- return;
-
- const ustring space_str = convert_utf8_to_utf32(std::string(" \t\n"));
- const bool shift = (state&base_window::KBD_MOD_SHIFT) != 0;
- const bool ctrl = (state&base_window::KBD_MOD_CONTROL) != 0;
- if (has_focus && enabled && !hidden)
- {
- if (shift && is_printable == false)
- {
- if (shift_pos == -1)
- {
- if (highlight_start <= highlight_end)
- {
- if (highlight_start == cursor_pos)
- shift_pos = highlight_end + 1;
- else
- shift_pos = highlight_start;
- }
- else
- {
- shift_pos = cursor_pos;
- }
- }
- }
- else
- {
- shift_pos = -1;
- }
-
- if (key == base_window::KEY_LEFT ||
- key == base_window::KEY_UP)
- {
- if (cursor_pos != 0)
- {
- unsigned long new_pos;
- if (ctrl)
- {
- // find the first non-whitespace to our left
- std::string::size_type pos = text_.find_last_not_of(space_str.c_str(),cursor_pos);
- if (pos != std::string::npos)
- {
- pos = text_.find_last_of(space_str.c_str(),pos);
- if (pos != std::string::npos)
- new_pos = static_cast<unsigned long>(pos);
- else
- new_pos = 0;
- }
- else
- {
- new_pos = 0;
- }
- }
- else
- {
- new_pos = cursor_pos-1;
- }
-
- move_cursor(new_pos);
- }
- else if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
-
- }
- else if (key == base_window::KEY_RIGHT ||
- key == base_window::KEY_DOWN)
- {
- if (cursor_pos != static_cast<long>(text_.size()))
- {
- unsigned long new_pos;
- if (ctrl)
- {
- // find the first non-whitespace to our left
- std::string::size_type pos = text_.find_first_not_of(space_str.c_str(),cursor_pos);
- if (pos != std::string::npos)
- {
- pos = text_.find_first_of(space_str.c_str(),pos);
- if (pos != std::string::npos)
- new_pos = static_cast<unsigned long>(pos+1);
- else
- new_pos = static_cast<unsigned long>(text_.size());
- }
- else
- {
- new_pos = static_cast<unsigned long>(text_.size());
- }
- }
- else
- {
- new_pos = cursor_pos+1;
- }
-
- move_cursor(new_pos);
- }
- else if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
- else if (is_printable)
- {
- if (ctrl)
- {
- if (key == 'a')
- {
- on_select_all();
- }
- else if (key == 'c')
- {
- on_copy();
- }
- else if (key == 'v')
- {
- on_paste();
- }
- else if (key == 'x')
- {
- on_cut();
- }
- }
- else if (key != '\n')
- {
- if (highlight_start <= highlight_end)
- {
- text_ = text_.substr(0,highlight_start) + static_cast<unichar>(key) +
- text_.substr(highlight_end+1,text_.size()-highlight_end-1);
- move_cursor(highlight_start+1);
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- else
- {
- text_ = text_.substr(0,cursor_pos) + static_cast<unichar>(key) +
- text_.substr(cursor_pos,text_.size()-cursor_pos);
- move_cursor(cursor_pos+1);
- }
- unsigned long height;
- mfont->compute_size(text_,text_width,height,text_pos);
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- else if (key == '\n')
- {
- if (enter_key_handler.is_set())
- enter_key_handler();
- }
- }
- else if (key == base_window::KEY_BACKSPACE)
- {
- // if something is highlighted then delete that
- if (highlight_start <= highlight_end)
- {
- on_delete_selected();
- }
- else if (cursor_pos != 0)
- {
- text_ = text_.erase(cursor_pos-1,1);
- move_cursor(cursor_pos-1);
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- else
- {
- // do this just so it repaints itself right
- move_cursor(cursor_pos);
- }
- unsigned long height;
- mfont->compute_size(text_,text_width,height,text_pos);
- parent.invalidate_rectangle(rect);
- }
- else if (key == base_window::KEY_DELETE)
- {
- // if something is highlighted then delete that
- if (highlight_start <= highlight_end)
- {
- on_delete_selected();
- }
- else if (cursor_pos != static_cast<long>(text_.size()))
- {
- text_ = text_.erase(cursor_pos,1);
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- else
- {
- // do this just so it repaints itself right
- move_cursor(cursor_pos);
- }
- parent.invalidate_rectangle(rect);
-
- unsigned long height;
- mfont->compute_size(text_,text_width,height,text_pos);
- }
- else if (key == base_window::KEY_HOME)
- {
- move_cursor(0);
- if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
- else if (key == base_window::KEY_END)
- {
- move_cursor(static_cast<unsigned long>(text_.size()));
- if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
- cursor_visible = true;
- recent_movement = true;
-
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- on_string_put(
- const std::wstring &str
- )
- {
- if (has_focus && enabled && !hidden){
- ustring ustr = convert_wstring_to_utf32(str);
- if (highlight_start <= highlight_end)
- {
- text_ = text_.substr(0,highlight_start) + ustr +
- text_.substr(highlight_end+1,text_.size()-highlight_end-1);
- move_cursor(highlight_start+ustr.size());
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- else
- {
- text_ = text_.substr(0,cursor_pos) + ustr +
- text_.substr(cursor_pos,text_.size()-cursor_pos);
- move_cursor(cursor_pos+ustr.size());
- }
- unsigned long height;
- mfont->compute_size(text_,text_width,height,text_pos);
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_field::
- move_cursor (
- unsigned long pos
- )
- {
- using namespace std;
- const long old_cursor_pos = cursor_pos;
-
- if (text_pos >= pos)
- {
- // the cursor should go all the way to the left side of the text
- if (pos >= 6)
- text_pos = pos-6;
- else
- text_pos = 0;
-
- cursor_pos = pos;
- unsigned long height;
- mfont->compute_size(text_,text_width,height,text_pos);
-
- unsigned long width;
- unsigned long new_x = style->get_padding(*mfont);
- if (static_cast<long>(cursor_pos)-1 >= static_cast<long>(text_pos))
- {
- mfont->compute_size(text_,width,height,text_pos,cursor_pos-1);
- if (cursor_pos != 0)
- new_x += width - mfont->right_overflow();
- }
-
- cursor_x = new_x;
- }
- else
- {
- unsigned long height;
- unsigned long width;
- mfont->compute_size(text_,width,height,text_pos,pos-1);
-
- unsigned long new_x = style->get_padding(*mfont) +
- width - mfont->right_overflow();
-
- // move the text to the left if necessary
- if (new_x + 4 > rect.width())
- {
- while (new_x > rect.width() - rect.width()/5)
- {
- new_x -= (*mfont)[text_[text_pos]].width();
- ++text_pos;
- }
- }
-
- cursor_x = new_x;
- cursor_pos = pos;
- mfont->compute_size(text_,text_width,height,text_pos);
- }
-
- parent.set_im_pos(rect.left()+cursor_x, rect.top());
-
- if (old_cursor_pos != cursor_pos)
- {
- if (shift_pos != -1)
- {
- highlight_start = std::min(shift_pos,cursor_pos);
- highlight_end = std::max(shift_pos,cursor_pos)-1;
- }
- else
- {
- highlight_start = 0;
- highlight_end = -1;
- }
-
- if (highlight_start > highlight_end)
- on_no_text_selected();
- else
- on_text_is_selected();
-
- recent_movement = true;
- cursor_visible = true;
- parent.invalidate_rectangle(rect);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// tabbed_display object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- tabbed_display::
- tabbed_display(
- drawable_window& w
- ) :
- drawable(w,MOUSE_CLICK),
- selected_tab_(0),
- left_pad(6),
- right_pad(4),
- top_pad(3),
- bottom_pad(3)
- {
- rect = rectangle(0,0,40,mfont->height()+top_pad+bottom_pad);
- enable_events();
- tabs.set_max_size(1);
- tabs.set_size(1);
- }
-
-// ----------------------------------------------------------------------------------------
-
- tabbed_display::
- ~tabbed_display(
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- set_pos (
- long x,
- long y
- )
- {
- auto_mutex M(m);
- // we have to adjust the positions of all the tab rectangles
- const long xdelta = rect.left() - x;
- const long ydelta = rect.top() - y;
- for (unsigned long i = 0; i < tabs.size(); ++i)
- {
- tabs[i].rect.set_left(tabs[i].rect.left()+xdelta);
- tabs[i].rect.set_right(tabs[i].rect.right()+xdelta);
-
- tabs[i].rect.set_top(tabs[i].rect.top()+ydelta);
- tabs[i].rect.set_bottom(tabs[i].rect.bottom()+ydelta);
-
-
- // adjust the position of the group associated with this tab if it exists
- if (tabs[i].group)
- tabs[i].group->set_pos(x+3, y+mfont->height()+top_pad+bottom_pad+3);
- }
- drawable::set_pos(x,y);
- recompute_tabs();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- fit_to_contents (
- )
- {
- auto_mutex M(m);
- rectangle new_rect;
- point p(rect.left(),rect.top());
- new_rect += p;
-
- for (unsigned long i = 0; i < tabs.size(); ++i)
- {
- if (tabs[i].group)
- {
- tabs[i].group->fit_to_contents();
- new_rect += tabs[i].group->get_rect();
- }
- }
-
- // and give the new rect an additional 4 pixels on the bottom and right sides
- // so that the contents to hit the edge of the tabbed display
- new_rect = resize_rect(new_rect, new_rect.width()+4, new_rect.height()+4);
-
- parent.invalidate_rectangle(new_rect+rect);
- rect = new_rect;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- rectangle old(rect);
- const long x = rect.left();
- const long y = rect.top();
- rect.set_right(x+width-1);
- rect.set_bottom(y+height-1);
-
- recompute_tabs();
-
- parent.invalidate_rectangle(rect+old);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- set_number_of_tabs (
- unsigned long num
- )
- {
- auto_mutex M(m);
-
- DLIB_ASSERT ( num > 0 ,
- "\tvoid tabbed_display::set_number_of_tabs()"
- << "\n\tnum: " << num );
-
- tabs.set_max_size(num);
- tabs.set_size(num);
-
- selected_tab_ = 0;
-
- recompute_tabs();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long tabbed_display::
- selected_tab (
- ) const
- {
- auto_mutex M(m);
- return selected_tab_;
- }
-
- unsigned long tabbed_display::
- number_of_tabs (
- ) const
- {
- auto_mutex M(m);
- return tabs.size();
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string tabbed_display::
- tab_name (
- unsigned long idx
- ) const
- {
- return convert_wstring_to_mbstring(tab_wname(idx));
- }
-
- const std::wstring tabbed_display::
- tab_wname (
- unsigned long idx
- ) const
- {
- return convert_utf32_to_wstring(tab_uname(idx));
- }
-
- const dlib::ustring& tabbed_display::
- tab_uname (
- unsigned long idx
- ) const
- {
- auto_mutex M(m);
-
- DLIB_ASSERT ( idx < number_of_tabs() ,
- "\tvoid tabbed_display::tab_name()"
- << "\n\tidx: " << idx
- << "\n\tnumber_of_tabs(): " << number_of_tabs() );
-
- return tabs[idx].name;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- set_tab_name (
- unsigned long idx,
- const std::string& new_name
- )
- {
- set_tab_name(idx, convert_mbstring_to_wstring(new_name));
- }
-
- void tabbed_display::
- set_tab_name (
- unsigned long idx,
- const std::wstring& new_name
- )
- {
- set_tab_name(idx, convert_wstring_to_utf32(new_name));
- }
-
- void tabbed_display::
- set_tab_name (
- unsigned long idx,
- const dlib::ustring& new_name
- )
- {
- auto_mutex M(m);
-
-
- DLIB_ASSERT ( idx < number_of_tabs() ,
- "\tvoid tabbed_display::set_tab_name()"
- << "\n\tidx: " << idx
- << "\n\tnumber_of_tabs(): " << number_of_tabs() );
-
-
- tabs[idx].name = new_name;
- // do this so that there isn't any reference counting going on
- tabs[idx].name[0] = tabs[idx].name[0];
- unsigned long height;
- mfont->compute_size(new_name,tabs[idx].width,height);
-
-
- recompute_tabs();
-
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- on_mouse_down (
- unsigned long btn,
- unsigned long,
- long x,
- long y,
- bool
- )
- {
- if (rect.contains(x,y) && btn == base_window::LEFT && enabled && !hidden)
- {
- rectangle temp = rect;
- const long offset = mfont->height() + bottom_pad + top_pad;
- temp.set_bottom(rect.top()+offset);
- if (temp.contains(x,y))
- {
- // now we have to figure out which tab was clicked
- for (unsigned long i = 0; i < tabs.size(); ++i)
- {
- if (selected_tab_ != i && tabs[i].rect.contains(x,y) &&
- tabs[selected_tab_].rect.contains(x,y) == false)
- {
- unsigned long old_idx = selected_tab_;
- selected_tab_ = i;
- recompute_tabs();
- parent.invalidate_rectangle(temp);
-
- // adjust the widget_group objects for these tabs if they exist
- if (tabs[i].group)
- tabs[i].group->show();
- if (tabs[old_idx].group)
- tabs[old_idx].group->hide();
-
- if (event_handler.is_set())
- event_handler(i,old_idx);
- break;
- }
- }
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- set_tab_group (
- unsigned long idx,
- widget_group& group
- )
- {
- auto_mutex M(m);
-
- DLIB_ASSERT ( idx < number_of_tabs() ,
- "\tvoid tabbed_display::set_tab_group()"
- << "\n\tidx: " << idx
- << "\n\tnumber_of_tabs(): " << number_of_tabs() );
-
-
- tabs[idx].group = &group;
- group.set_pos(rect.left()+3,rect.top()+mfont->height()+top_pad+bottom_pad+2);
- if (idx == selected_tab_)
- group.show();
- else
- group.hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- disable (
- )
- {
- auto_mutex M(m);
- if (tabs[selected_tab_].group)
- tabs[selected_tab_].group->disable();
- drawable::disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- enable (
- )
- {
- auto_mutex M(m);
- if (tabs[selected_tab_].group)
- tabs[selected_tab_].group->enable();
- drawable::enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- hide (
- )
- {
- auto_mutex M(m);
- if (tabs[selected_tab_].group)
- tabs[selected_tab_].group->hide();
- drawable::hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- show (
- )
- {
- auto_mutex M(m);
- if (tabs[selected_tab_].group)
- tabs[selected_tab_].group->show();
- drawable::show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- draw (
- const canvas& c
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- // draw the main border first
- rectangle main_box(rect.left(),rect.top()+mfont->height()+top_pad+bottom_pad,rect.right(),rect.bottom());
- draw_button_up(c,main_box);
- draw_pixel(c,point(main_box.right()-1,main_box.top()),rgb_pixel(128,128,128));
-
- rgb_pixel color;
- if (enabled)
- {
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- }
- else
- {
- color.red = 128;
- color.green = 128;
- color.blue = 128;
- }
-
- // draw the tabs
- for (unsigned long i = 0; i < tabs.size(); ++i)
- {
- if (selected_tab_ != i)
- draw_tab(tabs[i].rect,c);
-
- // draw the name string
- rectangle temp = tabs[i].rect;
- temp.set_top(temp.top()+top_pad);
- temp.set_bottom(temp.bottom()+bottom_pad);
- temp.set_left(temp.left()+left_pad);
- temp.set_right(temp.right()+right_pad);
- mfont->draw_string(c,temp,tabs[i].name,color);
- }
- draw_tab(tabs[selected_tab_].rect,c);
- draw_line(c,
- point(tabs[selected_tab_].rect.left()+1,
- tabs[selected_tab_].rect.bottom()),
- point(tabs[selected_tab_].rect.right()-2,
- tabs[selected_tab_].rect.bottom()),
- rgb_pixel(212,208,200));
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- draw_tab (
- const rectangle& tab,
- const canvas& c
- ) const
- {
- const rgb_pixel white(255,255,255);
- const rgb_pixel background(212,208,200);
- const rgb_pixel dark_gray(64,64,64);
- const rgb_pixel gray(128,128,128);
- draw_line(c,point(tab.left(),tab.top()+2),point(tab.left(),tab.bottom()),white);
- draw_line(c,point(tab.left()+1,tab.top()+2),point(tab.left()+1,tab.bottom()),background);
- draw_line(c,point(tab.right(),tab.top()+2),point(tab.right(),tab.bottom()),dark_gray);
- draw_line(c,point(tab.right()-1,tab.top()+2),point(tab.right()-1,tab.bottom()),gray);
- draw_line(c,point(tab.left()+2,tab.top()),point(tab.right()-2,tab.top()),white);
- draw_pixel(c,point(tab.left()+1,tab.top()+1),white);
- draw_pixel(c,point(tab.right()-1,tab.top()+1),dark_gray);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
-
- for (unsigned long i = 0; i < tabs.size(); ++i)
- {
- unsigned long height;
- mfont->compute_size(tabs[i].name,tabs[i].width,height);
- }
-
- recompute_tabs();
- set_pos(rect.left(), rect.top());
-
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void tabbed_display::
- recompute_tabs (
- )
- {
- const long offset = mfont->height() + bottom_pad + top_pad;
-
-
- // figure out the size and position of all the tabs
- rectangle sel_tab_rect, other_tab;
- sel_tab_rect.set_top(rect.top());
- sel_tab_rect.set_bottom(rect.top()+offset);
-
- other_tab.set_top(rect.top()+2);
- other_tab.set_bottom(rect.top()+offset-1);
-
- long cur_x = rect.left();
- for (unsigned long i = 0; i < tabs.size(); ++i)
- {
- const unsigned long str_width = tabs[i].width;
- if (selected_tab_ != i)
- {
- other_tab.set_left(cur_x);
- cur_x += left_pad + str_width + right_pad;
- other_tab.set_right(cur_x);
- tabs[i].rect = other_tab;
- ++cur_x;
-
- }
- else
- {
- if (i != 0)
- sel_tab_rect.set_left(cur_x-2);
- else
- sel_tab_rect.set_left(cur_x);
-
- cur_x += left_pad + str_width + right_pad;
-
- if (i != tabs.size()-1)
- sel_tab_rect.set_right(cur_x+2);
- else
- sel_tab_rect.set_right(cur_x);
- ++cur_x;
-
- tabs[i].rect = sel_tab_rect;
- }
- }
-
- // make sure this object is wide enough
- const rectangle& last = tabs[tabs.size()-1].rect;
- const rectangle& first = tabs[0].rect;
- rect = last + rect + first;
-
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// named_rectangle object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- named_rectangle::
- named_rectangle(
- drawable_window& w
- ) :
- drawable(w),
- name_width(0),
- name_height(0)
- {
- make_name_fit_in_rect();
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- named_rectangle::
- ~named_rectangle(
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void named_rectangle::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- rectangle old(rect);
- const long x = rect.left();
- const long y = rect.top();
- rect.set_right(x+width-1);
- rect.set_bottom(y+height-1);
-
- make_name_fit_in_rect();
- parent.invalidate_rectangle(rect+old);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void named_rectangle::
- wrap_around (
- const rectangle& r
- )
- {
- auto_mutex M(m);
- rectangle old(rect);
- const unsigned long pad = name_height/2;
-
- rect = rectangle(r.left()-pad, r.top()-name_height*4/3, r.right()+pad, r.bottom()+pad);
-
- make_name_fit_in_rect();
- parent.invalidate_rectangle(rect+old);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void named_rectangle::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- mfont->compute_size(name_,name_width,name_height);
- make_name_fit_in_rect();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void named_rectangle::
- make_name_fit_in_rect (
- )
- {
- // make sure the named rectangle is big enough to contain the name
- const unsigned long wtemp = mfont->height() + name_width;
- const unsigned long htemp = mfont->height() + name_height;
- if (rect.width() < wtemp)
- rect.set_right(rect.left() + wtemp - 1 );
- if (rect.height() < htemp)
- rect.set_bottom(rect.bottom() + htemp - 1 );
- }
-
-// ----------------------------------------------------------------------------------------
-
- void named_rectangle::
- set_name (
- const std::string& name
- )
- {
- set_name(convert_mbstring_to_wstring(name));
- }
-
- void named_rectangle::
- set_name (
- const std::wstring& name
- )
- {
- set_name(convert_wstring_to_utf32(name));
- }
-
- void named_rectangle::
- set_name (
- const dlib::ustring& name
- )
- {
- auto_mutex M(m);
- name_ = name.c_str();
- mfont->compute_size(name_,name_width,name_height);
-
- make_name_fit_in_rect();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string named_rectangle::
- name (
- ) const
- {
- return convert_wstring_to_mbstring(wname());
- }
-
- const std::wstring named_rectangle::
- wname (
- ) const
- {
- return convert_utf32_to_wstring(uname());
- }
-
- const dlib::ustring named_rectangle::
- uname (
- ) const
- {
- auto_mutex M(m);
- return dlib::ustring(name_.c_str());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void named_rectangle::
- draw (
- const canvas& c
- ) const
- {
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- const unsigned long gap = mfont->height()/2;
- rectangle strrect = rect;
- strrect.set_left(rect.left() + gap);
-
- const unsigned long rtop = rect.top() + name_height/2;
-
- const rgb_pixel white(255,255,255);
- const rgb_pixel gray(128,128,128);
-
- mfont->draw_string(c,strrect,name_);
- draw_line(c,point(rect.left(), rtop),
- point(rect.left()+gap/2, rtop), gray);
- draw_line(c,point(rect.left(), rtop),
- point(rect.left(), rect.bottom()-1), gray);
- draw_line(c,point(rect.left(), rect.bottom()-1),
- point(rect.right()-1, rect.bottom()-1), gray);
- draw_line(c,point(rect.right()-1, rtop),
- point(rect.right()-1, rect.bottom()-2), gray);
- draw_line(c,point(strrect.left() + name_width + 2, rtop),
- point(rect.right()-1, rtop), gray);
-
- draw_line(c,point(strrect.left() + name_width + 2, rtop+1),
- point( rect.right()-2, rtop+1), white);
- draw_line(c,point(rect.right(), rtop),
- point(rect.right(), rect.bottom()), white);
- draw_line(c,point(rect.left(), rect.bottom()),
- point(rect.right(), rect.bottom()), white);
- draw_line(c,point(rect.left()+1, rtop+1),
- point(rect.left()+1, rect.bottom()-2), white);
- draw_line(c,point(rect.left()+1, rtop+1),
- point(rect.left()+gap/2, rtop+1), white);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class mouse_tracker
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- mouse_tracker::
- mouse_tracker(
- drawable_window& w
- ) :
- draggable(w),
- offset(18),
- nr(w),
- x_label(w),
- y_label(w),
- click_x(-1),
- click_y(-1)
- {
- set_draggable_area(rectangle(0,0,500,500));
-
-
- x_label.set_text("x: ");
- y_label.set_text("y: ");
- nr.set_name("mouse position");
-
-
- x_label.set_pos(offset,offset);
- y_label.set_pos(x_label.get_rect().left(), x_label.get_rect().bottom()+3);
-
- nr.wrap_around(x_label.get_rect() + y_label.get_rect());
- rect = nr.get_rect();
-
- set_z_order(2000000000);
- x_label.set_z_order(2000000001);
- y_label.set_z_order(2000000001);
- nr.set_z_order(2000000001);
-
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- mouse_tracker::
- ~mouse_tracker(
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- nr.set_main_font(f);
- x_label.set_main_font(f);
- y_label.set_main_font(f);
- mfont = f;
- nr.wrap_around(x_label.get_rect() + y_label.get_rect());
- rect = nr.get_rect();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- set_pos (
- long x,
- long y
- )
- {
- draggable::set_pos(x,y);
- nr.set_pos(x,y);
- x_label.set_pos(rect.left()+offset,rect.top()+offset);
- y_label.set_pos(x_label.get_rect().left(), x_label.get_rect().bottom()+3);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- show (
- )
- {
- draggable::show();
- nr.show();
- x_label.show();
- y_label.show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- hide (
- )
- {
- draggable::hide();
- nr.hide();
- x_label.hide();
- y_label.hide();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- enable (
- )
- {
- draggable::enable();
- nr.enable();
- x_label.enable();
- y_label.enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- disable (
- )
- {
- draggable::disable();
- nr.disable();
- x_label.disable();
- y_label.disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool double_clicked
- )
- {
- draggable::on_mouse_down(btn,state,x,y,double_clicked);
- if ((state & base_window::SHIFT) && (btn == base_window::LEFT) && enabled && !hidden)
- {
- parent.invalidate_rectangle(rectangle(x,y,x,y));
- parent.invalidate_rectangle(rectangle(click_x,click_y,click_x,click_y));
- click_x = x;
- click_y = y;
-
- y_label.set_text("y: 0");
- x_label.set_text("x: 0");
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- if (!hidden && enabled)
- {
- parent.invalidate_rectangle(rect);
- draggable::on_mouse_move(state,x,y);
-
- long dx = 0;
- long dy = 0;
- if (click_x != -1)
- dx = click_x;
- if (click_y != -1)
- dy = click_y;
-
- sout.str("");
- sout << "y: " << y - dy;
- y_label.set_text(sout.str());
-
- sout.str("");
- sout << "x: " << x - dx;
- x_label.set_text(sout.str());
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- on_drag (
- )
- {
- nr.set_pos(rect.left(),rect.top());
- x_label.set_pos(rect.left()+offset,rect.top()+offset);
- y_label.set_pos(x_label.get_rect().left(), x_label.get_rect().bottom()+3);
-
- long x = 0;
- long y = 0;
- if (click_x != -1)
- x = click_x;
- if (click_y != -1)
- y = click_y;
-
- sout.str("");
- sout << "y: " << lasty - y;
- y_label.set_text(sout.str());
-
- sout.str("");
- sout << "x: " << lastx - x;
- x_label.set_text(sout.str());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void mouse_tracker::
- draw (
- const canvas& c
- ) const
- {
- fill_rect(c, rect,rgb_pixel(212,208,200));
- draw_pixel(c, point(click_x,click_y),rgb_pixel(255,0,0));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class list_box
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace list_box_helper{
- template <typename S>
- list_box<S>::
- list_box(
- drawable_window& w
- ) :
- scrollable_region(w,MOUSE_WHEEL|MOUSE_CLICK),
- ms_enabled(false),
- last_selected(0)
- {
- set_vertical_scroll_increment(mfont->height());
- set_horizontal_scroll_increment(mfont->height());
-
- style.reset(new list_box_style_default());
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- list_box<S>::
- ~list_box(
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- void list_box<S>::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- // recompute the sizes of all the items
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- mfont->compute_size(items[i].name,items[i].width, items[i].height);
- }
- set_vertical_scroll_increment(mfont->height());
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- bool list_box<S>::
- is_selected (
- unsigned long index
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( index < size() ,
- "\tbool list_box::is_selected(index)"
- << "\n\tindex: " << index
- << "\n\tsize(): " << size() );
-
- return items[index].is_selected;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- void list_box<S>::
- select (
- unsigned long index
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( index < size() ,
- "\tvoid list_box::select(index)"
- << "\n\tindex: " << index
- << "\n\tsize(): " << size() );
-
- last_selected = index;
- items[index].is_selected = true;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- void list_box<S>::
- unselect (
- unsigned long index
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( index < size() ,
- "\tvoid list_box::unselect(index)"
- << "\n\tindex: " << index
- << "\n\tsize(): " << size() );
- items[index].is_selected = false;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const S& list_box<S>::operator [] (
- unsigned long index
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( index < size() ,
- "\tconst std::string& list_box::operator[](index)"
- << "\n\tindex: " << index
- << "\n\tsize(): " << size() );
- return items[index].name;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- bool list_box<S>::
- multiple_select_enabled (
- ) const
- {
- auto_mutex M(m);
- return ms_enabled;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- void list_box<S>::
- enable_multiple_select (
- )
- {
- auto_mutex M(m);
- ms_enabled = true;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- void list_box<S>::
- disable_multiple_select (
- )
- {
- auto_mutex M(m);
- ms_enabled = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- bool list_box<S>::
- at_start (
- ) const
- {
- auto_mutex M(m);
- return items.at_start();
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- void list_box<S>::
- reset (
- ) const
- {
- auto_mutex M(m);
- items.reset();
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- bool list_box<S>::
- current_element_valid (
- ) const
- {
- auto_mutex M(m);
- return items.current_element_valid();
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const S &list_box<S>::
- element (
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( current_element_valid() ,
- "\tconst std::string& list_box::element()"
- );
- return items.element().name;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const S &list_box<S>::
- element (
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( current_element_valid() ,
- "\tconst std::string& list_box::element()"
- );
- return items.element().name;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- bool list_box<S>::
- move_next (
- ) const
- {
- auto_mutex M(m);
- return items.move_next();
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- size_t list_box<S>::
- size (
- ) const
- {
- auto_mutex M(m);
- return items.size();
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- void list_box<S>::
- draw (
- const canvas& c
- ) const
- {
- scrollable_region::draw(c);
-
- rectangle area = display_rect().intersect(c);
- if (area.is_empty())
- return;
-
- style->draw_list_box_background(c, display_rect(), enabled);
-
- long y = total_rect().top();
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- if (y+(long)items[i].height <= area.top())
- {
- y += items[i].height;
- continue;
- }
-
- rectangle r(total_rect().left(), y, display_rect().right(), y+items[i].height-1);
-
- style->draw_list_box_item(c,r, display_rect(), enabled, *mfont, items[i].name, items[i].is_selected);
-
-
- y += items[i].height;
-
- if (y > area.bottom())
- break;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- void list_box<S>::
- on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- )
- {
- if (display_rect().contains(x,y) && btn == base_window::LEFT && enabled && !hidden )
- {
- if ( ms_enabled == false ||
- ((!(state&base_window::CONTROL)) && !(state&base_window::SHIFT)))
- {
- items.reset();
- while (items.move_next())
- {
- items.element().is_selected = false;
- }
- }
-
- y -= total_rect().top();
- long h = 0;
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- h += items[i].height;
- if (h >= y)
- {
- if (ms_enabled)
- {
- if (state&base_window::CONTROL)
- {
- items[i].is_selected = !items[i].is_selected;
- if (items[i].is_selected)
- last_selected = i;
- }
- else if (state&base_window::SHIFT)
- {
- // we want to select everything between (and including) the
- // current thing clicked and last_selected.
- const unsigned long first = std::min(i,last_selected);
- const unsigned long last = std::max(i,last_selected);
- for (unsigned long j = first; j <= last; ++j)
- items[j].is_selected = true;
- }
- else
- {
- items[i].is_selected = true;
- last_selected = i;
- if (is_double_click && event_handler.is_set())
- event_handler(i);
- else if (single_click_event_handler.is_set())
- single_click_event_handler(i);
- }
- }
- else
- {
- items[i].is_selected = true;
- last_selected = i;
- if (is_double_click && event_handler.is_set())
- event_handler(i);
- else if (single_click_event_handler.is_set())
- single_click_event_handler(i);
- }
-
- break;
- }
- }
-
- parent.invalidate_rectangle(rect);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- unsigned long list_box<S>::
- get_selected (
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( multiple_select_enabled() == false,
- "\tunsigned long list_box::get_selected()"
- );
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- if (items[i].is_selected)
- return i;
- }
- return items.size();
- }
-// ----------------------------------------------------------------------------------------
-
- // making instance of template
- template class list_box<std::string>;
- template class list_box<std::wstring>;
- template class list_box<dlib::ustring>;
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // function message_box()
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace message_box_helper
- {
- void box_win::
- initialize (
- )
- {
- msg.set_pos(20,20);
- msg.set_text(message);
- rectangle msg_rect = msg.get_rect();
- btn_ok.set_name("OK");
- btn_ok.set_size(60,btn_ok.height());
- if (msg_rect.width() >= 60)
- btn_ok.set_pos(msg_rect.width()/2+msg_rect.left()-btn_ok.width()/2,msg_rect.bottom()+15);
- else
- btn_ok.set_pos(20,msg_rect.bottom()+15);
- btn_ok.set_click_handler(*this,&box_win::on_click);
-
- rectangle size = btn_ok.get_rect() + msg_rect;
- set_size(size.right()+20,size.bottom()+20);
-
-
- show();
- set_title(title);
- }
-
- // ------------------------------------------------------------------------------------
-
- box_win::
- box_win (
- const std::string& title_,
- const std::string& message_
- ) :
- drawable_window(false),
- title(convert_mbstring_to_wstring(title_)),
- message(convert_mbstring_to_wstring(message_)),
- msg(*this),
- btn_ok(*this)
- {
- initialize();
- }
-
- // ------------------------------------------------------------------------------------
-
- box_win::
- box_win (
- const std::wstring& title_,
- const std::wstring& message_
- ) :
- drawable_window(false),
- title(title_),
- message(message_),
- msg(*this),
- btn_ok(*this)
- {
- initialize();
- }
-
- // ------------------------------------------------------------------------------------
-
- box_win::
- box_win (
- const dlib::ustring& title_,
- const dlib::ustring& message_
- ) :
- drawable_window(false),
- title(convert_utf32_to_wstring(title_)),
- message(convert_utf32_to_wstring(message_)),
- msg(*this),
- btn_ok(*this)
- {
- initialize();
- }
-
- // ------------------------------------------------------------------------------------
-
- box_win::
- ~box_win (
- )
- {
- close_window();
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- deleter_thread (
- void* param
- )
- {
- // The point of this extra event_handler stuff is to allow the user
- // to end the program from within the callback. So we want to destroy the
- // window *before* we call their callback.
- box_win& w = *static_cast<box_win*>(param);
- w.close_window();
- any_function<void()> event_handler(w.event_handler);
- delete &w;
- if (event_handler.is_set())
- event_handler();
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_click (
- )
- {
- hide();
- create_new_thread(&deleter_thread,this);
- }
-
- // ------------------------------------------------------------------------------------
-
- base_window::on_close_return_code box_win::
- on_window_close (
- )
- {
- // The point of this extra event_handler stuff is to allow the user
- // to end the program within the callback. So we want to destroy the
- // window *before* we call their callback.
- any_function<void()> event_handler_copy(event_handler);
- delete this;
- if (event_handler_copy.is_set())
- event_handler_copy();
- return CLOSE_WINDOW;
- }
-
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
-
- void blocking_box_win::
- initialize (
- )
- {
- msg.set_pos(20,20);
- msg.set_text(message);
- rectangle msg_rect = msg.get_rect();
- btn_ok.set_name("OK");
- btn_ok.set_size(60,btn_ok.height());
- if (msg_rect.width() >= 60)
- btn_ok.set_pos(msg_rect.width()/2+msg_rect.left()-btn_ok.width()/2,msg_rect.bottom()+15);
- else
- btn_ok.set_pos(20,msg_rect.bottom()+15);
- btn_ok.set_click_handler(*this,&blocking_box_win::on_click);
-
- rectangle size = btn_ok.get_rect() + msg_rect;
- set_size(size.right()+20,size.bottom()+20);
-
-
- set_title(title);
- show();
- }
-
- // ------------------------------------------------------------------------------------
-
- blocking_box_win::
- blocking_box_win (
- const std::string& title_,
- const std::string& message_
- ) :
- drawable_window(false),
- title(convert_mbstring_to_wstring(title_)),
- message(convert_mbstring_to_wstring(message_)),
- msg(*this),
- btn_ok(*this)
- {
- initialize();
- }
-
- // ------------------------------------------------------------------------------------
-
- blocking_box_win::
- blocking_box_win (
- const std::wstring& title_,
- const std::wstring& message_
- ) :
- drawable_window(false),
- title(title_),
- message(message_),
- msg(*this),
- btn_ok(*this)
- {
- initialize();
- }
-
- // ------------------------------------------------------------------------------------
-
- blocking_box_win::
- blocking_box_win (
- const dlib::ustring& title_,
- const dlib::ustring& message_
- ) :
- drawable_window(false),
- title(convert_utf32_to_wstring(title_)),
- message(convert_utf32_to_wstring(message_)),
- msg(*this),
- btn_ok(*this)
- {
- initialize();
- }
-
- // ------------------------------------------------------------------------------------
-
- blocking_box_win::
- ~blocking_box_win (
- )
- {
- close_window();
- }
-
- // ------------------------------------------------------------------------------------
-
- void blocking_box_win::
- on_click (
- )
- {
- close_window();
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // function open_file_box()
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace open_file_box_helper
- {
- box_win::
- box_win (
- const std::string& title,
- bool has_text_field
- ) :
- lbl_dirs(*this),
- lbl_files(*this),
- lbl_file_name(*this),
- lb_dirs(*this),
- lb_files(*this),
- btn_ok(*this),
- btn_cancel(*this),
- btn_root(*this),
- tf_file_name(*this)
- {
- if (has_text_field == false)
- {
- tf_file_name.hide();
- lbl_file_name.hide();
- }
- else
- {
- lbl_file_name.set_text("File: ");
- }
-
- cur_dir = -1;
- set_size(500,300);
-
- lbl_dirs.set_text("Directories:");
- lbl_files.set_text("Files:");
- btn_ok.set_name("Ok");
- btn_cancel.set_name("Cancel");
- btn_root.set_name("/");
-
- btn_root.set_click_handler(*this,&box_win::on_root_click);
- btn_cancel.set_click_handler(*this,&box_win::on_cancel_click);
- btn_ok.set_click_handler(*this,&box_win::on_open_click);
- lb_dirs.set_double_click_handler(*this,&box_win::on_dirs_click);
- lb_files.set_click_handler(*this,&box_win::on_files_click);
- lb_files.set_double_click_handler(*this,&box_win::on_files_double_click);
-
-
- btn_root.set_pos(5,5);
-
- set_sizes();
- set_title(title);
-
- on_root_click();
-
- // make it so that the file box starts out in our current working
- // directory
- std::string full_name(get_current_dir());
-
- while (full_name.size() > 0)
- {
- std::string::size_type pos = full_name.find_first_of("\\/");
- std::string left(full_name.substr(0,pos));
- if (pos != std::string::npos)
- full_name = full_name.substr(pos+1);
- else
- full_name.clear();
-
- if (left.size() > 0)
- enter_folder(left);
- }
-
-
- show();
- }
-
- // ------------------------------------------------------------------------------------
-
- box_win::
- ~box_win (
- )
- {
- close_window();
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- set_sizes(
- )
- {
- unsigned long width, height;
- get_size(width,height);
-
-
- if (lbl_file_name.is_hidden())
- {
- lbl_dirs.set_pos(0,btn_root.bottom()+5);
- lb_dirs.set_pos(0,lbl_dirs.bottom());
- lb_dirs.set_size(width/2,height-lb_dirs.top()-btn_cancel.height()-10);
-
- lbl_files.set_pos(lb_dirs.right(),btn_root.bottom()+5);
- lb_files.set_pos(lb_dirs.right(),lbl_files.bottom());
- lb_files.set_size(width-lb_files.left(),height-lb_files.top()-btn_cancel.height()-10);
-
- btn_ok.set_pos(width - btn_ok.width()-25,lb_files.bottom()+5);
- btn_cancel.set_pos(btn_ok.left() - btn_cancel.width()-5,lb_files.bottom()+5);
- }
- else
- {
-
- lbl_dirs.set_pos(0,btn_root.bottom()+5);
- lb_dirs.set_pos(0,lbl_dirs.bottom());
- lb_dirs.set_size(width/2,height-lb_dirs.top()-btn_cancel.height()-10-tf_file_name.height());
-
- lbl_files.set_pos(lb_dirs.right(),btn_root.bottom()+5);
- lb_files.set_pos(lb_dirs.right(),lbl_files.bottom());
- lb_files.set_size(width-lb_files.left(),height-lb_files.top()-btn_cancel.height()-10-tf_file_name.height());
-
- lbl_file_name.set_pos(lb_files.left(), lb_files.bottom()+8);
- tf_file_name.set_pos(lbl_file_name.right(), lb_files.bottom()+5);
- tf_file_name.set_width(width-tf_file_name.left()-5);
-
- btn_ok.set_pos(width - btn_ok.width()-25,tf_file_name.bottom()+5);
- btn_cancel.set_pos(btn_ok.left() - btn_cancel.width()-5,tf_file_name.bottom()+5);
- }
-
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_window_resized (
- )
- {
- set_sizes();
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- deleter_thread (
- )
- {
- close_window();
- delete this;
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- enter_folder (
- const std::string& folder_name
- )
- {
- if (btn_root.is_checked())
- btn_root.set_unchecked();
- if (cur_dir != -1)
- sob[cur_dir]->set_unchecked();
-
-
- const std::string old_path = path;
- const long old_cur_dir = cur_dir;
-
- std::unique_ptr<toggle_button> new_btn(new toggle_button(*this));
- new_btn->set_name(folder_name);
- new_btn->set_click_handler(*this,&box_win::on_path_button_click);
-
- // remove any path buttons that won't be part of the path anymore
- if (sob.size())
- {
- while (sob.size() > (unsigned long)(cur_dir+1))
- {
- std::unique_ptr<toggle_button> junk;
- sob.remove(cur_dir+1,junk);
- }
- }
-
- if (sob.size())
- new_btn->set_pos(sob[sob.size()-1]->right()+5,sob[sob.size()-1]->top());
- else
- new_btn->set_pos(btn_root.right()+5,btn_root.top());
-
- cur_dir = sob.size();
- sob.add(sob.size(),new_btn);
-
- path += folder_name + directory::get_separator();
- if (set_dir(prefix + path) == false)
- {
- sob.remove(sob.size()-1,new_btn);
- path = old_path;
- cur_dir = old_cur_dir;
- }
- else
- {
-
- sob[cur_dir]->set_checked();
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_dirs_click (
- unsigned long idx
- )
- {
- enter_folder(lb_dirs[idx]);
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_files_click (
- unsigned long idx
- )
- {
- if (tf_file_name.is_hidden() == false)
- {
- tf_file_name.set_text(lb_files[idx]);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_files_double_click (
- unsigned long
- )
- {
- on_open_click();
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_cancel_click (
- )
- {
- hide();
- create_new_thread<box_win,&box_win::deleter_thread>(*this);
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_open_click (
- )
- {
- if (lb_files.get_selected() != lb_files.size() || tf_file_name.text().size() > 0)
- {
- if (event_handler.is_set())
- {
- if (tf_file_name.is_hidden())
- event_handler(prefix + path + lb_files[lb_files.get_selected()]);
- else if (tf_file_name.text().size() > 0)
- event_handler(prefix + path + tf_file_name.text());
- }
- hide();
- create_new_thread<box_win,&box_win::deleter_thread>(*this);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_path_button_click (
- toggle_button& btn
- )
- {
- if (btn_root.is_checked())
- btn_root.set_unchecked();
- if (cur_dir != -1)
- sob[cur_dir]->set_unchecked();
- std::string new_path;
-
- for (unsigned long i = 0; i < sob.size(); ++i)
- {
- new_path += sob[i]->name() + directory::get_separator();
- if (sob[i].get() == &btn)
- {
- cur_dir = i;
- sob[i]->set_checked();
- break;
- }
- }
- if (path != new_path)
- {
- path = new_path;
- set_dir(prefix+path);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- struct case_insensitive_compare
- {
- bool operator() (
- const std::string& a,
- const std::string& b
- ) const
- {
- std::string::size_type i, size;
- size = std::min(a.size(),b.size());
- for (i = 0; i < size; ++i)
- {
- if (std::tolower(a[i]) < std::tolower(b[i]))
- return true;
- else if (std::tolower(a[i]) > std::tolower(b[i]))
- return false;
- }
- if (a.size() < b.size())
- return true;
- else
- return false;
- }
- };
-
- // ------------------------------------------------------------------------------------
-
- bool box_win::
- set_dir (
- const std::string& dir
- )
- {
- try
- {
- directory d(dir);
- queue<directory>::kernel_1a_c qod;
- queue<file>::kernel_1a_c qof;
- queue<std::string>::sort_1a_c qos;
- d.get_dirs(qod);
- d.get_files(qof);
-
- qod.reset();
- while (qod.move_next())
- {
- std::string temp = qod.element().name();
- qos.enqueue(temp);
- }
- qos.sort(case_insensitive_compare());
- lb_dirs.load(qos);
- qos.clear();
-
- qof.reset();
- while (qof.move_next())
- {
- std::string temp = qof.element().name();
- qos.enqueue(temp);
- }
- qos.sort(case_insensitive_compare());
- lb_files.load(qos);
- return true;
- }
- catch (directory::listing_error& )
- {
- return false;
- }
- catch (directory::dir_not_found&)
- {
- return false;
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- void box_win::
- on_root_click (
- )
- {
- btn_root.set_checked();
- if (cur_dir != -1)
- sob[cur_dir]->set_unchecked();
-
- queue<directory>::kernel_1a_c qod, qod2;
- queue<file>::kernel_1a_c qof;
- queue<std::string>::sort_1a_c qos;
- get_filesystem_roots(qod);
- path.clear();
- cur_dir = -1;
- if (qod.size() == 1)
- {
- qod.current().get_files(qof);
- qod.current().get_dirs(qod2);
- prefix = qod.current().full_name();
-
- qod2.reset();
- while (qod2.move_next())
- {
- std::string temp = qod2.element().name();
- qos.enqueue(temp);
- }
- qos.sort(case_insensitive_compare());
- lb_dirs.load(qos);
- qos.clear();
-
- qof.reset();
- while (qof.move_next())
- {
- std::string temp = qof.element().name();
- qos.enqueue(temp);
- }
- qos.sort(case_insensitive_compare());
- lb_files.load(qos);
- }
- else
- {
- prefix.clear();
- qod.reset();
- while (qod.move_next())
- {
- std::string temp = qod.element().full_name();
- temp = temp.substr(0,temp.size()-1);
- qos.enqueue(temp);
- }
- qos.sort(case_insensitive_compare());
- lb_dirs.load(qos);
- qos.clear();
- lb_files.load(qos);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- base_window::on_close_return_code box_win::
- on_window_close (
- )
- {
- delete this;
- return CLOSE_WINDOW;
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class menu_bar
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- menu_bar::
- menu_bar(
- drawable_window& w
- ) :
- drawable(w, 0xFFFF), // listen for all events
- open_menu(0)
- {
- adjust_position();
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- menu_bar::
- ~menu_bar()
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- adjust_position();
- compute_menu_geometry();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- set_number_of_menus (
- unsigned long num
- )
- {
- auto_mutex M(m);
- menus.set_max_size(num);
- menus.set_size(num);
- open_menu = menus.size();
- compute_menu_geometry();
-
- for (unsigned long i = 0; i < menus.size(); ++i)
- {
- menus[i].menu.set_on_hide_handler(*this,&menu_bar::on_popup_hide);
- }
-
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long menu_bar::
- number_of_menus (
- ) const
- {
- auto_mutex M(m);
- return menus.size();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- set_menu_name (
- unsigned long idx,
- const std::string name,
- char underline_ch
- )
- {
- set_menu_name(idx, convert_mbstring_to_wstring(name), underline_ch);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- set_menu_name (
- unsigned long idx,
- const std::wstring name,
- char underline_ch
- )
- {
- set_menu_name(idx, convert_wstring_to_utf32(name), underline_ch);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- set_menu_name (
- unsigned long idx,
- const dlib::ustring name,
- char underline_ch
- )
- {
- DLIB_ASSERT ( idx < number_of_menus() ,
- "\tvoid menu_bar::set_menu_name()"
- << "\n\tidx: " << idx
- << "\n\tnumber_of_menus(): " << number_of_menus()
- );
- auto_mutex M(m);
- menus[idx].name = name.c_str();
- menus[idx].underline_pos = name.find_first_of(underline_ch);
- compute_menu_geometry();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string menu_bar::
- menu_name (
- unsigned long idx
- ) const
- {
- return convert_wstring_to_mbstring(menu_wname(idx));
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::wstring menu_bar::
- menu_wname (
- unsigned long idx
- ) const
- {
- return convert_utf32_to_wstring(menu_uname(idx));
- }
-
-// ----------------------------------------------------------------------------------------
-
- const dlib::ustring menu_bar::
- menu_uname (
- unsigned long idx
- ) const
- {
- DLIB_ASSERT ( idx < number_of_menus() ,
- "\tstd::string menu_bar::menu_name()"
- << "\n\tidx: " << idx
- << "\n\tnumber_of_menus(): " << number_of_menus()
- );
- auto_mutex M(m);
- return menus[idx].name.c_str();
- }
-
-// ----------------------------------------------------------------------------------------
-
- popup_menu& menu_bar::
- menu (
- unsigned long idx
- )
- {
- DLIB_ASSERT ( idx < number_of_menus() ,
- "\tpopup_menu& menu_bar::menu()"
- << "\n\tidx: " << idx
- << "\n\tnumber_of_menus(): " << number_of_menus()
- );
- auto_mutex M(m);
- return menus[idx].menu;
- }
-
-// ----------------------------------------------------------------------------------------
-
- const popup_menu& menu_bar::
- menu (
- unsigned long idx
- ) const
- {
- DLIB_ASSERT ( idx < number_of_menus() ,
- "\tconst popup_menu& menu_bar::menu()"
- << "\n\tidx: " << idx
- << "\n\tnumber_of_menus(): " << number_of_menus()
- );
- auto_mutex M(m);
- return menus[idx].menu;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- on_window_resized (
- )
- {
- adjust_position();
- hide_menu();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- draw (
- const canvas& c
- ) const
- {
- rectangle area(rect.intersect(c));
- if (area.is_empty())
- return;
-
- const unsigned char opacity = 40;
- fill_rect_with_vertical_gradient(c, rect,rgb_alpha_pixel(255,255,255,opacity),
- rgb_alpha_pixel(0,0,0,opacity));
-
- // first draw the border between the menu and the rest of the window
- draw_line(c, point(rect.left(),rect.bottom()-1),
- point(rect.right(),rect.bottom()-1), 100);
- draw_line(c, point(rect.left(),rect.bottom()),
- point(rect.right(),rect.bottom()), 255);
-
- // now draw all the menu buttons
- for (unsigned long i = 0; i < menus.size(); ++i)
- {
- mfont->draw_string(c,menus[i].rect, menus[i].name );
- if (menus[i].underline_p1 != menus[i].underline_p2)
- draw_line(c, menus[i].underline_p1, menus[i].underline_p2);
-
- if (open_menu == i)
- {
- fill_rect_with_vertical_gradient(c, menus[i].bgrect,rgb_alpha_pixel(255,255,0,40), rgb_alpha_pixel(0,0,0,40));
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- on_window_moved (
- )
- {
- hide_menu();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- on_focus_lost (
- )
- {
- hide_menu();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- )
- {
-
- if (rect.contains(x,y) == false || btn != (unsigned long)base_window::LEFT)
- {
- hide_menu();
- return;
- }
-
- unsigned long old_menu = menus.size();
-
- // if a menu is currently open then save its index
- if (open_menu != menus.size())
- {
- old_menu = open_menu;
- hide_menu();
- }
-
- // figure out which menu should be open if any
- for (unsigned long i = 0; i < menus.size(); ++i)
- {
- if (menus[i].bgrect.contains(x,y))
- {
- if (old_menu != i)
- show_menu(i);
-
- break;
- }
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- on_mouse_move (
- unsigned long ,
- long x,
- long y
- )
- {
- // if the mouse is over the menu_bar and some menu is currently open
- if (rect.contains(x,y) && open_menu != menus.size())
- {
- // if the mouse is still in the same rectangle then don't do anything
- if (menus[open_menu].bgrect.contains(x,y) == false)
- {
- // figure out which menu should be instead
- for (unsigned long i = 0; i < menus.size(); ++i)
- {
- if (menus[i].bgrect.contains(x,y))
- {
- show_menu(i);
- break;
- }
- }
-
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- )
- {
- if (state&base_window::KBD_MOD_ALT)
- {
- // check if the key matches any of our underlined keys
- for (unsigned long i = 0; i < menus.size(); ++i)
- {
- // if we have found a matching key
- if (is_printable &&
- menus[i].underline_pos != std::string::npos &&
- std::tolower(menus[i].name[menus[i].underline_pos]) == std::tolower(key))
- {
- show_menu(i);
- menus[open_menu].menu.select_first_item();
- return;
- }
- }
- }
-
- if (open_menu != menus.size())
- {
- unsigned long i = open_menu;
- // if the submenu doesn't use this key for something then we will
- if (menus[open_menu].menu.forwarded_on_keydown(key,is_printable,state) == false)
- {
- if (key == base_window::KEY_LEFT)
- {
- i = (i+menus.size()-1)%menus.size();
- show_menu(i);
- menus[open_menu].menu.select_first_item();
- }
- else if (key == base_window::KEY_RIGHT)
- {
- i = (i+1)%menus.size();
- show_menu(i);
- menus[open_menu].menu.select_first_item();
- }
- else if (key == base_window::KEY_ESC)
- {
- hide_menu();
- }
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- show_menu (
- unsigned long i
- )
- {
- rectangle temp;
-
- // menu already open so do nothing
- if (i == open_menu)
- return;
-
- // if a menu is currently open
- if (open_menu != menus.size())
- {
- menus[open_menu].menu.hide();
- temp = menus[open_menu].bgrect;
- }
-
- // display the new menu
- open_menu = i;
- long wx, wy;
- parent.get_pos(wx,wy);
- wx += menus[i].bgrect.left();
- wy += menus[i].bgrect.bottom()+1;
- menus[i].menu.set_pos(wx,wy);
- menus[i].menu.show();
- parent.invalidate_rectangle(menus[i].bgrect+temp);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- hide_menu (
- )
- {
- // if a menu is currently open
- if (open_menu != menus.size())
- {
- menus[open_menu].menu.hide();
- parent.invalidate_rectangle(menus[open_menu].bgrect);
- open_menu = menus.size();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- on_popup_hide (
- )
- {
- // if a menu is currently open
- if (open_menu != menus.size())
- {
- parent.invalidate_rectangle(menus[open_menu].bgrect);
- open_menu = menus.size();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- compute_menu_geometry (
- )
- {
- long x = 7;
- long bg_x = 0;
- for (unsigned long i = 0; i < menus.size(); ++i)
- {
- // compute the locations of the text rectangles
- menus[i].rect.set_top(5);
- menus[i].rect.set_left(x);
- menus[i].rect.set_bottom(rect.bottom()-2);
-
- unsigned long width, height;
- mfont->compute_size(menus[i].name,width,height);
- menus[i].rect = resize_rect_width(menus[i].rect, width);
- x = menus[i].rect.right()+10;
-
- menus[i].bgrect.set_top(0);
- menus[i].bgrect.set_left(bg_x);
- menus[i].bgrect.set_bottom(rect.bottom()-2);
- menus[i].bgrect.set_right(x-5);
- bg_x = menus[i].bgrect.right()+1;
-
- if (menus[i].underline_pos != std::string::npos)
- {
- // now compute the location of the underline bar
- rectangle r1 = mfont->compute_cursor_rect(
- menus[i].rect,
- menus[i].name,
- menus[i].underline_pos);
-
- rectangle r2 = mfont->compute_cursor_rect(
- menus[i].rect,
- menus[i].name,
- menus[i].underline_pos+1);
-
- menus[i].underline_p1.x() = r1.left()+1;
- menus[i].underline_p2.x() = r2.left()-1;
- menus[i].underline_p1.y() = r1.bottom()-mfont->height()+mfont->ascender()+2;
- menus[i].underline_p2.y() = r2.bottom()-mfont->height()+mfont->ascender()+2;
- }
- else
- {
- // there is no underline in this case
- menus[i].underline_p1 = menus[i].underline_p2;
- }
-
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void menu_bar::
- adjust_position (
- )
- {
- unsigned long width, height;
- rectangle old(rect);
- parent.get_size(width,height);
- rect.set_left(0);
- rect.set_top(0);
- rect = resize_rect(rect,width,mfont->height()+10);
- parent.invalidate_rectangle(old+rect);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// class text_grid
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- text_grid::
- text_grid (
- drawable_window& w
- ) :
- scrollable_region(w, KEYBOARD_EVENTS | MOUSE_CLICK | FOCUS_EVENTS ),
- has_focus(false),
- cursor_timer(*this,&text_grid::timer_action),
- border_color_(128,128,128)
- {
-
- cursor_timer.set_delay_time(500);
- set_vertical_scroll_increment(10);
- set_horizontal_scroll_increment(10);
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- text_grid::
- ~text_grid (
- )
- {
- // Disable all further events for this drawable object. We have to do this
- // because we don't want draw() events coming to this object while or after
- // it has been destructed.
- disable_events();
-
- // wait for the timer to stop doing its thing
- cursor_timer.stop_and_wait();
- // Tell the parent window to redraw its area that previously contained this
- // drawable object.
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_grid_size (
- unsigned long rows,
- unsigned long cols
- )
- {
- auto_mutex M(m);
- row_height.set_max_size(rows);
- row_height.set_size(rows);
-
- col_width.set_max_size(cols);
- col_width.set_size(cols);
-
- grid.set_size(rows,cols);
-
- for (unsigned long i = 0; i < row_height.size(); ++i)
- row_height[i] = (mfont->height()*3)/2;
- for (unsigned long i = 0; i < col_width.size(); ++i)
- col_width[i] = mfont->height()*5;
-
- compute_total_rect();
- compute_bg_rects();
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long text_grid::
- number_of_columns (
- ) const
- {
- auto_mutex M(m);
- return grid.nc();
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long text_grid::
- number_of_rows (
- ) const
- {
- auto_mutex M(m);
- return grid.nr();
- }
-
-// ----------------------------------------------------------------------------------------
-
- int text_grid::
- next_free_user_event_number (
- ) const
- {
- return scrollable_region::next_free_user_event_number()+1;
- }
-
-// ----------------------------------------------------------------------------------------
-
- rgb_pixel text_grid::
- border_color (
- ) const
- {
- auto_mutex M(m);
- return border_color_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_border_color (
- rgb_pixel color
- )
- {
- auto_mutex M(m);
- border_color_ = color;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string text_grid::
- text (
- unsigned long row,
- unsigned long col
- ) const
- {
- return convert_wstring_to_mbstring(wtext(row, col));
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::wstring text_grid::
- wtext (
- unsigned long row,
- unsigned long col
- ) const
- {
- return convert_utf32_to_wstring(utext(row, col));
- }
-
-// ----------------------------------------------------------------------------------------
-
- const dlib::ustring text_grid::
- utext (
- unsigned long row,
- unsigned long col
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() && col < number_of_columns(),
- "\tconst std::string text_grid::text(row,col)"
- << "\n\trow: " << row
- << "\n\tcol: " << col
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\tthis: " << this
- );
- return grid[row][col].text.c_str();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_text (
- unsigned long row,
- unsigned long col,
- const std::string& str
- )
- {
- set_text(row, col, convert_mbstring_to_wstring(str));
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_text (
- unsigned long row,
- unsigned long col,
- const std::wstring& str
- )
- {
- set_text(row, col, convert_wstring_to_utf32(str));
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_text (
- unsigned long row,
- unsigned long col,
- const dlib::ustring& str
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() && col < number_of_columns(),
- "\tvoid text_grid::set_text(row,col)"
- << "\n\trow: " << row
- << "\n\tcol: " << col
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\tthis: " << this
- );
- grid[row][col].text = str.c_str();
- parent.invalidate_rectangle(get_text_rect(row,col));
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rgb_pixel text_grid::
- text_color (
- unsigned long row,
- unsigned long col
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() && col < number_of_columns(),
- "\tconst rgb_pixel text_grid::text_color(row,col)"
- << "\n\trow: " << row
- << "\n\tcol: " << col
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\tthis: " << this
- );
- return grid[row][col].text_color;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_text_color (
- unsigned long row,
- unsigned long col,
- const rgb_pixel color
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() && col < number_of_columns(),
- "\tvoid text_grid::set_text_color(row,col,color)"
- << "\n\trow: " << row
- << "\n\tcol: " << col
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\tthis: " << this
- );
- grid[row][col].text_color = color;
- parent.invalidate_rectangle(get_text_rect(row,col));
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rgb_pixel text_grid::
- background_color (
- unsigned long row,
- unsigned long col
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() && col < number_of_columns(),
- "\tconst rgb_pixel text_grid::background_color(row,col,color)"
- << "\n\trow: " << row
- << "\n\tcol: " << col
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\tthis: " << this
- );
- return grid[row][col].bg_color;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_background_color (
- unsigned long row,
- unsigned long col,
- const rgb_pixel color
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() && col < number_of_columns(),
- "\tvoid text_grid::set_background_color(row,col,color)"
- << "\n\trow: " << row
- << "\n\tcol: " << col
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\tthis: " << this
- );
- grid[row][col].bg_color = color;
- parent.invalidate_rectangle(get_bg_rect(row,col));
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool text_grid::
- is_editable (
- unsigned long row,
- unsigned long col
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() && col < number_of_columns(),
- "\tbool text_grid::is_editable(row,col)"
- << "\n\trow: " << row
- << "\n\tcol: " << col
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\tthis: " << this
- );
- return grid[row][col].is_editable;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_editable (
- unsigned long row,
- unsigned long col,
- bool editable
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() && col < number_of_columns(),
- "\tvoid text_grid::set_editable(row,col,editable)"
- << "\n\trow: " << row
- << "\n\tcol: " << col
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\teditable: " << editable
- << "\n\tthis: " << this
- );
- grid[row][col].is_editable = editable;
- if (has_focus && active_row == static_cast<long>(row) && active_col == static_cast<long>(col))
- {
- drop_input_focus();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_column_width (
- unsigned long col,
- unsigned long width
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( col < number_of_columns(),
- "\tvoid text_grid::set_column_width(col,width)"
- << "\n\tcol: " << col
- << "\n\tnumber_of_columns(): " << number_of_columns()
- << "\n\twidth: " << width
- << "\n\tthis: " << this
- );
- col_width[col] = width;
- compute_total_rect();
- compute_bg_rects();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- set_row_height (
- unsigned long row,
- unsigned long height
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( row < number_of_rows() ,
- "\tvoid text_grid::set_row_height(row,height)"
- << "\n\trow: " << row
- << "\n\tnumber_of_rows(): " << number_of_rows()
- << "\n\theight: " << height
- << "\n\tthis: " << this
- );
- row_height[row] = height;
- compute_total_rect();
- compute_bg_rects();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- disable (
- )
- {
- auto_mutex M(m);
- scrollable_region::disable();
- drop_input_focus();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- hide (
- )
- {
- auto_mutex M(m);
- scrollable_region::hide();
- drop_input_focus();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- on_user_event (
- int num
- )
- {
- // ignore this user event if it isn't for us
- if (num != scrollable_region::next_free_user_event_number())
- return;
-
- if (has_focus && !recent_cursor_move && enabled && !hidden)
- {
- show_cursor = !show_cursor;
- parent.invalidate_rectangle(get_text_rect(active_row,active_col));
- }
- recent_cursor_move = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- timer_action (
- )
- {
- parent.trigger_user_event(this,scrollable_region::next_free_user_event_number());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- compute_bg_rects (
- )
- {
- // loop over each element in the grid and figure out what its rectangle should be
- // with respect to the total_rect()
- point p1, p2;
- p1.y() = total_rect().top();
- for (long row = 0; row < grid.nr(); ++row)
- {
- p1.x() = total_rect().left();
- p2.y() = p1.y() + row_height[row]-1;
- for (long col = 0; col < grid.nc(); ++col)
- {
- // if this is the last box in this row make it super wide so that it always
- // goes to the end of the widget
- if (col+1 == grid.nc())
- p2.x() = 1000000;
- else
- p2.x() = p1.x() + col_width[col]-1;
-
- // at this point p1 is the upper left corner of this box and p2 is the
- // lower right corner of the box;
- rectangle bg_rect(p1);
- bg_rect += p2;
-
- grid[row][col].bg_rect = translate_rect(bg_rect, -total_rect().left(), -total_rect().top());
-
-
- p1.x() += 1 + col_width[col];
- }
- p1.y() += 1 + row_height[row];
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- compute_total_rect (
- )
- {
- if (grid.size() == 0)
- {
- set_total_rect_size(0,0);
- }
- else
- {
- unsigned long width = col_width.size()-1;
- unsigned long height = row_height.size()-1;
-
- for (unsigned long i = 0; i < col_width.size(); ++i)
- width += col_width[i];
- for (unsigned long i = 0; i < row_height.size(); ++i)
- height += row_height[i];
-
- set_total_rect_size(width,height);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- )
- {
- // ignore this event if we are disabled or hidden
- if (!enabled || hidden)
- return;
-
- if (has_focus)
- {
- if (is_printable)
- {
- // if the user hit the tab key then jump to the next box
- if (key == '\t')
- {
- if (active_col+1 == grid.nc())
- {
- if (active_row+1 == grid.nr())
- move_cursor(0,0,0);
- else
- move_cursor(active_row+1,0,0);
- }
- else
- {
- move_cursor(active_row,active_col+1,0);
- }
- }
- if (key == '\n')
- {
- // ignore the enter key
- }
- else if (grid[active_row][active_col].is_editable)
- {
- // insert the key the user pressed into the string
- grid[active_row][active_col].text.insert(cursor_pos,1,static_cast<char>(key));
- move_cursor(active_row,active_col,cursor_pos+1);
-
- if (text_modified_handler.is_set())
- text_modified_handler(active_row,active_col);
- }
- }
- else if ((state & base_window::KBD_MOD_CONTROL))
- {
- if (key == base_window::KEY_LEFT)
- move_cursor(active_row,active_col-1,0);
- else if (key == base_window::KEY_RIGHT)
- move_cursor(active_row,active_col+1,0);
- else if (key == base_window::KEY_UP)
- move_cursor(active_row-1,active_col,0);
- else if (key == base_window::KEY_DOWN)
- move_cursor(active_row+1,active_col,0);
- else if (key == base_window::KEY_END)
- move_cursor(active_row,active_col,grid[active_row][active_col].text.size());
- else if (key == base_window::KEY_HOME)
- move_cursor(active_row,active_col,0);
- }
- else
- {
- if (key == base_window::KEY_LEFT)
- move_cursor(active_row,active_col,cursor_pos-1);
- else if (key == base_window::KEY_RIGHT)
- move_cursor(active_row,active_col,cursor_pos+1);
- else if (key == base_window::KEY_UP)
- move_cursor(active_row-1,active_col,0);
- else if (key == base_window::KEY_DOWN)
- move_cursor(active_row+1,active_col,0);
- else if (key == base_window::KEY_END)
- move_cursor(active_row,active_col,grid[active_row][active_col].text.size());
- else if (key == base_window::KEY_HOME)
- move_cursor(active_row,active_col,0);
- else if (key == base_window::KEY_BACKSPACE)
- {
- if (cursor_pos > 0 && grid[active_row][active_col].is_editable)
- {
- grid[active_row][active_col].text.erase(
- grid[active_row][active_col].text.begin()+cursor_pos-1,
- grid[active_row][active_col].text.begin()+cursor_pos);
- move_cursor(active_row,active_col,cursor_pos-1);
-
- if (text_modified_handler.is_set())
- text_modified_handler(active_row,active_col);
- }
- }
- else if (key == base_window::KEY_DELETE)
- {
- if (cursor_pos < static_cast<long>(grid[active_row][active_col].text.size()) &&
- grid[active_row][active_col].is_editable)
- {
- grid[active_row][active_col].text.erase(
- grid[active_row][active_col].text.begin()+cursor_pos);
- move_cursor(active_row,active_col,cursor_pos);
-
- if (text_modified_handler.is_set())
- text_modified_handler(active_row,active_col);
- }
- }
- }
- } // if (has_focus)
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- )
- {
- scrollable_region::on_mouse_down(btn, state, x, y, is_double_click);
- if (display_rect().contains(x,y) && enabled && !hidden)
- {
- // figure out which box this click landed in
- rectangle hit;
-
- // find which column we hit
- unsigned long col = 0;
- long box_x = total_rect().left();
- for (unsigned long i = 0; i < col_width.size(); ++i)
- {
- if (box_x <= x && (x < box_x+static_cast<long>(col_width[i]) || (i+1 == col_width.size())))
- {
- col = i;
- hit.set_left(box_x);
- hit.set_right(box_x+col_width[i]-1);
- break;
- }
- else
- {
- box_x += col_width[i]+1;
- }
- }
-
- // find which row we hit
- unsigned long row = 0;
- long box_y = total_rect().top();
- for (unsigned long i = 0; i < row_height.size(); ++i)
- {
- if (box_y <= y && y < box_y+static_cast<long>(row_height[i]))
- {
- row = i;
- hit.set_top(box_y);
- hit.set_bottom(box_y+row_height[i]-1);
- break;
- }
- else
- {
- box_y += row_height[i]+1;
- }
- }
-
- // if we hit a box
- if (hit.is_empty() == false)
- {
- move_cursor(row,
- col,
- mfont->compute_cursor_pos(get_text_rect(row,col), grid[row][col].text, x, y, grid[row][col].first)
- );
- }
- else
- {
- drop_input_focus();
- }
- }
- else
- {
- drop_input_focus();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- )
- {
- scrollable_region::on_mouse_up(btn, state, x, y);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- on_focus_lost (
- )
- {
- drop_input_focus();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- draw (
- const canvas& c
- ) const
- {
- scrollable_region::draw(c);
- rectangle area = c.intersect(display_rect());
- if (area.is_empty() == true)
- return;
-
- if (enabled)
- fill_rect(c, area, 255);
-
- // don't do anything if the grid is empty
- if (grid.size() == 0)
- return;
-
- // draw all the vertical lines
- point p1, p2;
- p1.x() = p2.x() = total_rect().left();
- p1.y() = total_rect().top();
- p2.y() = total_rect().bottom();
- for (unsigned long i = 0; i < col_width.size()-1; ++i)
- {
- p1.x() += col_width[i];
- p2.x() += col_width[i];
- if (enabled)
- draw_line(c,p1,p2,border_color_,area);
- else
- draw_line(c,p1,p2,128,area);
- p1.x() += 1;
- p2.x() += 1;
- }
-
- // draw all the horizontal lines
- p1.y() = p2.y() = total_rect().top();
- p1.x() = display_rect().left();
- p2.x() = display_rect().right();
- for (unsigned long i = 0; i < row_height.size(); ++i)
- {
- p1.y() += row_height[i];
- p2.y() += row_height[i];
- if (enabled)
- draw_line(c,p1,p2,border_color_,area);
- else
- draw_line(c,p1,p2,128,area);
- p1.y() += 1;
- p2.y() += 1;
- }
-
- // draw the backgrounds and text for each box
- for (long row = 0; row < grid.nr(); ++row)
- {
- for (long col = 0; col < grid.nc(); ++col)
- {
- rectangle bg_rect(get_bg_rect(row,col));
-
- rectangle text_rect(get_text_rect(row,col));
-
- if (enabled)
- {
- fill_rect(c,bg_rect.intersect(area),grid[row][col].bg_color);
-
- mfont->draw_string(c,
- text_rect,
- grid[row][col].text,
- grid[row][col].text_color,
- grid[row][col].first,
- std::string::npos,
- area);
- }
- else
- {
- mfont->draw_string(c,
- text_rect,
- grid[row][col].text,
- 128,
- grid[row][col].first,
- std::string::npos,
- area);
- }
-
- // if this box has input focus then draw it with a cursor
- if (has_focus && active_col == col && active_row == row && show_cursor)
- {
- rectangle cursor_rect = mfont->compute_cursor_rect(text_rect,
- grid[row][col].text,
- cursor_pos,
- grid[row][col].first);
- draw_rectangle(c,cursor_rect,0,area);
- }
-
- }
- }
-
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle text_grid::
- get_text_rect (
- unsigned long row,
- unsigned long col
- ) const
- {
- rectangle bg_rect(get_bg_rect(row,col));
- long padding = (bg_rect.height() - mfont->height())/2 + (bg_rect.height() - mfont->height())%2;
- if (padding < 0)
- padding = 0;
- bg_rect.set_left(bg_rect.left()+padding);
- bg_rect.set_top(bg_rect.top()+padding);
- bg_rect.set_right(bg_rect.right()-padding);
- bg_rect.set_bottom(bg_rect.bottom()-padding);
- return bg_rect;
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle text_grid::
- get_bg_rect (
- unsigned long row,
- unsigned long col
- ) const
- {
- return translate_rect(grid[row][col].bg_rect, total_rect().left(), total_rect().top());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- drop_input_focus (
- )
- {
- if (has_focus)
- {
- parent.invalidate_rectangle(get_text_rect(active_row,active_col));
- has_focus = false;
- show_cursor = false;
- cursor_timer.stop();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_grid::
- move_cursor (
- long row,
- long col,
- long new_cursor_pos
- )
- {
- // don't do anything if the grid is empty
- if (grid.size() == 0)
- {
- return;
- }
-
- if (row < 0)
- row = 0;
- if (row >= grid.nr())
- row = grid.nr()-1;
- if (col < 0)
- col = 0;
- if (col >= grid.nc())
- col = grid.nc()-1;
-
- if (new_cursor_pos < 0)
- {
- if (col == 0)
- {
- new_cursor_pos = 0;
- }
- else
- {
- --col;
- new_cursor_pos = grid[row][col].text.size();
- }
- }
-
- if (new_cursor_pos > static_cast<long>(grid[row][col].text.size()))
- {
- if (col+1 == grid.nc())
- {
- new_cursor_pos = grid[row][col].text.size();
- }
- else
- {
- ++col;
- new_cursor_pos = 0;
- }
- }
-
- // if some other box had the input focus then redraw it
- if (has_focus && (active_row != row || active_col != col ))
- {
- parent.invalidate_rectangle(get_text_rect(active_row,active_col));
- }
-
- if (has_focus == false)
- {
- cursor_timer.start();
- }
-
- has_focus = true;
- recent_cursor_move = true;
- show_cursor = true;
- active_row = row;
- active_col = col;
- cursor_pos = new_cursor_pos;
-
- // adjust the first character to draw so that the string is displayed well
- rectangle text_rect(get_text_rect(active_row,active_col));
- rectangle cursor_rect = mfont->compute_cursor_rect(text_rect,
- grid[row][col].text,
- cursor_pos,
- grid[row][col].first);
-
- // if the cursor rect is too far to the left of the string
- if (cursor_pos < static_cast<long>(grid[row][col].first))
- {
- if (cursor_pos > 5)
- {
- grid[row][col].first = cursor_pos - 5;
- }
- else
- {
- grid[row][col].first = 0;
- }
- }
- // if the cursor rect is too far to the right of the string
- else if (cursor_rect.left() > text_rect.right())
- {
- long distance = (cursor_rect.left() - text_rect.right()) + text_rect.width()/3;
- // find the letter that is distance pixels from the start of the string
- long sum = 0;
- for (unsigned long i = grid[row][col].first; i < grid[row][col].text.size(); ++i)
- {
- sum += (*mfont)[grid[row][col].text[i]].width();
- if (sum >= distance)
- {
- grid[row][col].first = i;
- break;
- }
- }
- }
-
- scroll_to_rect(get_bg_rect(row,col));
-
- // redraw our box
- parent.invalidate_rectangle(text_rect);
-
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // text_field object methods
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- rectangle text_box::
- get_text_rect (
- ) const
- {
- const unsigned long padding = style->get_padding(*mfont);
-
- rectangle text_rect;
- text_rect.set_left(total_rect().left()+padding);
- text_rect.set_top(total_rect().top()+padding);
- text_rect.set_right(total_rect().right()-padding);
- text_rect.set_bottom(total_rect().bottom()-padding);
- return text_rect;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- enable (
- )
- {
- scrollable_region::enable();
- right_click_menu.enable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_cut (
- )
- {
- on_copy();
- on_delete_selected();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_copy (
- )
- {
- if (highlight_start <= highlight_end)
- {
- put_on_clipboard(text_.substr(highlight_start, highlight_end-highlight_start+1));
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_paste (
- )
- {
- ustring temp_str;
- get_from_clipboard(temp_str);
-
-
- if (highlight_start <= highlight_end)
- {
- text_ = text_.substr(0,highlight_start) + temp_str +
- text_.substr(highlight_end+1,text_.size()-highlight_end-1);
- move_cursor(highlight_start+temp_str.size());
- highlight_start = 0;
- highlight_end = -1;
- parent.invalidate_rectangle(rect);
- on_no_text_selected();
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- else
- {
- text_ = text_.substr(0,cursor_pos) + temp_str +
- text_.substr(cursor_pos,text_.size()-cursor_pos);
- move_cursor(cursor_pos+temp_str.size());
-
- // send out the text modified event
- if (temp_str.size() != 0 && text_modified_handler.is_set())
- text_modified_handler();
- }
-
- adjust_total_rect();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_select_all (
- )
- {
- move_cursor(static_cast<long>(text_.size()));
- highlight_start = 0;
- highlight_end = static_cast<long>(text_.size()-1);
- if (highlight_start <= highlight_end)
- on_text_is_selected();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_delete_selected (
- )
- {
- if (highlight_start <= highlight_end)
- {
- text_ = text_.erase(highlight_start,highlight_end-highlight_start+1);
- move_cursor(highlight_start);
- highlight_start = 0;
- highlight_end = -1;
-
- on_no_text_selected();
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
-
- adjust_total_rect();
-
- parent.invalidate_rectangle(rect);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_text_is_selected (
- )
- {
- right_click_menu.menu().enable_menu_item(0);
- right_click_menu.menu().enable_menu_item(1);
- right_click_menu.menu().enable_menu_item(3);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_no_text_selected (
- )
- {
- right_click_menu.menu().disable_menu_item(0);
- right_click_menu.menu().disable_menu_item(1);
- right_click_menu.menu().disable_menu_item(3);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- show (
- )
- {
- scrollable_region::show();
- right_click_menu.show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- disable (
- )
- {
- auto_mutex M(m);
- scrollable_region::disable();
- t.stop();
- has_focus = false;
- cursor_visible = false;
- right_click_menu.disable();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- hide (
- )
- {
- auto_mutex M(m);
- scrollable_region::hide();
- t.stop();
- has_focus = false;
- cursor_visible = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- adjust_total_rect (
- )
- {
- const unsigned long padding = style->get_padding(*mfont);
- unsigned long text_width;
- unsigned long text_height;
-
- mfont->compute_size(text_, text_width, text_height);
-
- set_total_rect_size(text_width + padding*2, text_height + padding*2);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- set_main_font (
- const std::shared_ptr<font>& f
- )
- {
- auto_mutex M(m);
- mfont = f;
- adjust_total_rect();
- right_click_menu.set_rect(display_rect());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- draw (
- const canvas& c
- ) const
- {
- scrollable_region::draw(c);
- rectangle area = rect.intersect(c);
- if (area.is_empty())
- return;
-
- const point origin(total_rect().left(), total_rect().top());
-
- style->draw_text_box(c,display_rect(),get_text_rect(), enabled, *mfont, text_,
- translate_rect(cursor_rect, origin),
- text_color_, bg_color_, has_focus, cursor_visible, highlight_start,
- highlight_end);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- set_text (
- const std::string& text
- )
- {
- set_text(convert_mbstring_to_wstring(text));
- }
-
- void text_box::
- set_text (
- const std::wstring& text
- )
- {
- set_text(convert_wstring_to_utf32(text));
- }
-
- void text_box::
- set_text (
- const dlib::ustring& text
- )
- {
- auto_mutex M(m);
- // do this to get rid of any reference counting that may be present in
- // the std::string implementation.
- text_ = text.c_str();
-
- adjust_total_rect();
- move_cursor(0);
-
- highlight_start = 0;
- highlight_end = -1;
- }
-
-// ----------------------------------------------------------------------------------------
-
- const std::string text_box::
- text (
- ) const
- {
- std::string temp = convert_wstring_to_mbstring(wtext());
- return temp;
- }
-
- const std::wstring text_box::
- wtext (
- ) const
- {
- std::wstring temp = convert_utf32_to_wstring(utext());
- return temp;
- }
-
- const dlib::ustring text_box::
- utext (
- ) const
- {
- auto_mutex M(m);
- // do this to get rid of any reference counting that may be present in
- // the dlib::ustring implementation.
- dlib::ustring temp = text_.c_str();
- return temp;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex M(m);
- scrollable_region::set_size(width,height);
- right_click_menu.set_rect(display_rect());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- set_pos (
- long x,
- long y
- )
- {
- scrollable_region::set_pos(x,y);
- right_click_menu.set_rect(get_text_rect());
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- set_background_color (
- const rgb_pixel color
- )
- {
- auto_mutex M(m);
- bg_color_ = color;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rgb_pixel text_box::
- background_color (
- ) const
- {
- auto_mutex M(m);
- return bg_color_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- set_text_color (
- const rgb_pixel color
- )
- {
- auto_mutex M(m);
- text_color_ = color;
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- const rgb_pixel text_box::
- text_color (
- ) const
- {
- auto_mutex M(m);
- return text_color_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- if (!enabled || hidden || !has_focus)
- {
- return;
- }
-
- if (state & base_window::LEFT)
- {
- if (highlight_start <= highlight_end)
- {
- if (highlight_start == cursor_pos)
- shift_pos = highlight_end + 1;
- else
- shift_pos = highlight_start;
- }
-
- unsigned long new_pos = mfont->compute_cursor_pos(get_text_rect(),text_,x,y);
- if (static_cast<long>(new_pos) != cursor_pos)
- {
- move_cursor(new_pos);
- parent.invalidate_rectangle(rect);
- }
- }
- else if (shift_pos != -1)
- {
- shift_pos = -1;
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_mouse_up (
- unsigned long btn,
- unsigned long,
- long ,
- long
- )
- {
- if (!enabled || hidden)
- return;
-
- if (btn == base_window::LEFT)
- shift_pos = -1;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool double_clicked
- )
- {
- using namespace std;
- if (!enabled || hidden || btn != (unsigned long)base_window::LEFT)
- return;
-
- if (display_rect().contains(x,y))
- {
- has_focus = true;
- cursor_visible = true;
- parent.invalidate_rectangle(rect);
- t.start();
-
-
- if (double_clicked)
- {
- // highlight the double clicked word
- string::size_type first, last;
- const ustring ustr = convert_utf8_to_utf32(std::string(" \t\n"));
- first = text_.substr(0,cursor_pos).find_last_of(ustr.c_str());
- last = text_.find_first_of(ustr.c_str(),cursor_pos);
- long f = static_cast<long>(first);
- long l = static_cast<long>(last);
- if (first == string::npos)
- f = -1;
- if (last == string::npos)
- l = static_cast<long>(text_.size());
-
- ++f;
- --l;
-
- move_cursor(l+1);
- highlight_start = f;
- highlight_end = l;
- on_text_is_selected();
- }
- else
- {
- if (state & base_window::SHIFT)
- {
- if (highlight_start <= highlight_end)
- {
- if (highlight_start == cursor_pos)
- shift_pos = highlight_end + 1;
- else
- shift_pos = highlight_start;
- }
- else
- {
- shift_pos = cursor_pos;
- }
- }
-
- bool at_end = false;
- if (cursor_pos == 0 || cursor_pos == static_cast<long>(text_.size()))
- at_end = true;
- const long old_pos = cursor_pos;
-
- unsigned long new_pos = mfont->compute_cursor_pos(get_text_rect(),text_,x,y);
- move_cursor(new_pos);
-
- shift_pos = cursor_pos;
-
- if (at_end && cursor_pos == old_pos)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- }
- }
-
- }
- else if (has_focus && rect.contains(x,y) == false)
- {
- t.stop();
- has_focus = false;
- cursor_visible = false;
- shift_pos = -1;
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
-
- if (focus_lost_handler.is_set())
- focus_lost_handler();
- parent.invalidate_rectangle(rect);
- }
- else
- {
- has_focus = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- )
- {
- // If the right click menu is up then we don't want to do anything with
- // the keyboard ourselves. Let the popup menu use the keyboard for now.
- if (right_click_menu.popup_menu_visible())
- return;
-
- if (has_focus && enabled && !hidden)
- {
- const ustring space_str = convert_utf8_to_utf32(std::string(" \t\n"));
- const bool shift = (state&base_window::KBD_MOD_SHIFT) != 0;
- const bool ctrl = (state&base_window::KBD_MOD_CONTROL) != 0;
-
- if (shift && is_printable == false)
- {
- if (shift_pos == -1)
- {
- if (highlight_start <= highlight_end)
- {
- if (highlight_start == cursor_pos)
- shift_pos = highlight_end + 1;
- else
- shift_pos = highlight_start;
- }
- else
- {
- shift_pos = cursor_pos;
- }
- }
- }
- else
- {
- shift_pos = -1;
- }
-
- if (key == base_window::KEY_LEFT)
- {
- if (cursor_pos != 0)
- {
- unsigned long new_pos;
- if (ctrl)
- {
- // find the first non-whitespace to our left
- std::string::size_type pos = text_.find_last_not_of(space_str.c_str(),cursor_pos);
- if (pos != std::string::npos)
- {
- pos = text_.find_last_of(space_str.c_str(),pos);
- if (pos != std::string::npos)
- new_pos = static_cast<unsigned long>(pos);
- else
- new_pos = 0;
- }
- else
- {
- new_pos = 0;
- }
- }
- else
- {
- new_pos = cursor_pos-1;
- }
-
- move_cursor(new_pos);
- }
- else if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
-
- }
- else if (key == base_window::KEY_RIGHT)
- {
- if (cursor_pos != static_cast<long>(text_.size()))
- {
- unsigned long new_pos;
- if (ctrl)
- {
- // find the first non-whitespace to our left
- std::string::size_type pos = text_.find_first_not_of(space_str.c_str(),cursor_pos);
- if (pos != std::string::npos)
- {
- pos = text_.find_first_of(space_str.c_str(),pos);
- if (pos != std::string::npos)
- new_pos = static_cast<unsigned long>(pos+1);
- else
- new_pos = static_cast<unsigned long>(text_.size());
- }
- else
- {
- new_pos = static_cast<unsigned long>(text_.size());
- }
- }
- else
- {
- new_pos = cursor_pos+1;
- }
-
- move_cursor(new_pos);
- }
- else if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
- else if (key == base_window::KEY_UP)
- {
- if (ctrl)
- {
- move_cursor(0);
- }
- else
- {
- const point origin(total_rect().left(), total_rect().top());
- // move the cursor so the position that is just a few pixels above
- // the current cursor_rect
- move_cursor(mfont->compute_cursor_pos(
- get_text_rect(), text_, cursor_rect.left()+origin.x(),
- cursor_rect.top()+origin.y()-mfont->height()/2));
-
- }
-
- if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
- else if (key == base_window::KEY_DOWN)
- {
- if (ctrl)
- {
- move_cursor(static_cast<unsigned long>(text_.size()));
- }
- else
- {
- const point origin(total_rect().left(), total_rect().top());
- // move the cursor so the position that is just a few pixels above
- // the current cursor_rect
- move_cursor(mfont->compute_cursor_pos(
- get_text_rect(), text_, cursor_rect.left()+origin.x(),
- cursor_rect.bottom()+origin.y()+mfont->height()/2));
- }
-
- if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
- else if (is_printable)
- {
- if (ctrl)
- {
- if (key == 'a')
- {
- on_select_all();
- }
- else if (key == 'c')
- {
- on_copy();
- }
- else if (key == 'v')
- {
- on_paste();
- }
- else if (key == 'x')
- {
- on_cut();
- }
- }
- else
- {
- if (highlight_start <= highlight_end)
- {
- text_ = text_.substr(0,highlight_start) + static_cast<unichar>(key) +
- text_.substr(highlight_end+1,text_.size()-highlight_end-1);
-
- adjust_total_rect();
- move_cursor(highlight_start+1);
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- }
- else
- {
- text_ = text_.substr(0,cursor_pos) + static_cast<unichar>(key) +
- text_.substr(cursor_pos,text_.size()-cursor_pos);
- adjust_total_rect();
- move_cursor(cursor_pos+1);
- }
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
-
- }
-
- if (key == '\n')
- {
- if (enter_key_handler.is_set())
- enter_key_handler();
- }
- }
- else if (key == base_window::KEY_BACKSPACE)
- {
- // if something is highlighted then delete that
- if (highlight_start <= highlight_end)
- {
- on_delete_selected();
- }
- else if (cursor_pos != 0)
- {
- text_ = text_.erase(cursor_pos-1,1);
- adjust_total_rect();
- move_cursor(cursor_pos-1);
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- else
- {
- // do this just so it repaints itself right
- move_cursor(cursor_pos);
- }
-
- }
- else if (key == base_window::KEY_DELETE)
- {
- // if something is highlighted then delete that
- if (highlight_start <= highlight_end)
- {
- on_delete_selected();
- }
- else if (cursor_pos != static_cast<long>(text_.size()))
- {
- text_ = text_.erase(cursor_pos,1);
-
- adjust_total_rect();
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- else
- {
- // do this just so it repaints itself right
- move_cursor(cursor_pos);
- }
-
- }
- else if (key == base_window::KEY_HOME)
- {
- if (ctrl)
- {
- move_cursor(0);
- }
- else if (cursor_pos != 0)
- {
- // find the start of the current line
- ustring::size_type pos = text_.find_last_of('\n',cursor_pos-1);
- if (pos == ustring::npos)
- pos = 0;
- else
- pos += 1;
- move_cursor(static_cast<unsigned long>(pos));
-
- }
-
- if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
- else if (key == base_window::KEY_END)
- {
- if (ctrl)
- {
- move_cursor(static_cast<unsigned long>(text_.size()));
- }
- {
- ustring::size_type pos = text_.find_first_of('\n',cursor_pos);
- if (pos == ustring::npos)
- pos = text_.size();
-
- move_cursor(static_cast<unsigned long>(pos));
- }
-
- if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- parent.invalidate_rectangle(rect);
- }
- }
- else if (key == base_window::KEY_PAGE_DOWN || key == base_window::KEY_PAGE_UP)
- {
- long jump_size = display_rect().height() -
- std::min(mfont->height()*3, display_rect().height()/5);
-
- // if we are supposed to page up then just jump in the other direction
- if (key == base_window::KEY_PAGE_UP)
- jump_size = -jump_size;
-
- scroll_to_rect(translate_rect(display_rect(), point(0, jump_size )));
- }
-
- cursor_visible = true;
- recent_movement = true;
-
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- on_string_put(
- const std::wstring &str
- )
- {
- if (has_focus && enabled && !hidden)
- {
- ustring ustr = convert_wstring_to_utf32(str);
- if (highlight_start <= highlight_end)
- {
- text_ = text_.substr(0,highlight_start) + ustr +
- text_.substr(highlight_end+1,text_.size()-highlight_end-1);
-
- adjust_total_rect();
- move_cursor(highlight_start+ustr.size());
- highlight_start = 0;
- highlight_end = -1;
- on_no_text_selected();
- }
- else
- {
- text_ = text_.substr(0,cursor_pos) + ustr +
- text_.substr(cursor_pos,text_.size()-cursor_pos);
-
- adjust_total_rect();
- move_cursor(cursor_pos+ustr.size());
- }
-
-
- // send out the text modified event
- if (text_modified_handler.is_set())
- text_modified_handler();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void text_box::
- move_cursor (
- unsigned long pos
- )
- {
- using namespace std;
- const long old_cursor_pos = cursor_pos;
-
-
-
- // figure out where the cursor is supposed to be
- cursor_rect = mfont->compute_cursor_rect(get_text_rect(), text_, pos);
- const point origin(total_rect().left(), total_rect().top());
-
-
- cursor_pos = pos;
-
-
- const unsigned long padding = style->get_padding(*mfont);
-
- // now scroll us so that we can see the current cursor
- scroll_to_rect(centered_rect(cursor_rect, cursor_rect.width() + padding + 6, cursor_rect.height() + 1));
-
- // adjust the cursor_rect so that it is relative to the total_rect
- cursor_rect = translate_rect(cursor_rect, -origin);
-
- parent.set_im_pos(cursor_rect.left(), cursor_rect.top());
-
- if (old_cursor_pos != cursor_pos)
- {
- if (shift_pos != -1)
- {
- highlight_start = std::min(shift_pos,cursor_pos);
- highlight_end = std::max(shift_pos,cursor_pos)-1;
- }
-
- if (highlight_start > highlight_end)
- on_no_text_selected();
- else
- on_text_is_selected();
-
- recent_movement = true;
- cursor_visible = true;
- parent.invalidate_rectangle(display_rect());
- }
-
- if (shift_pos == -1)
- {
- highlight_start = 0;
- highlight_end = -1;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// perspective_display member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- perspective_display::
- perspective_display(
- drawable_window& w
- ) :
- drawable(w,MOUSE_MOVE|MOUSE_CLICK|MOUSE_WHEEL)
- {
- clear_overlay();
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- perspective_display::
- ~perspective_display(
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex lock(m);
- rectangle old(rect);
- rect = resize_rect(rect,width,height);
- tform = camera_transform(tform.get_camera_pos(),
- tform.get_camera_looking_at(),
- tform.get_camera_up_direction(),
- tform.get_camera_field_of_view(),
- std::min(rect.width(),rect.height()));
- parent.invalidate_rectangle(old+rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- add_overlay (
- const std::vector<overlay_line>& overlay
- )
- {
- auto_mutex M(m);
- if (overlay.size() == 0)
- return;
- // push this new overlay into our overlay vector
- overlay_lines.insert(overlay_lines.end(), overlay.begin(), overlay.end());
-
- for (unsigned long i = 0; i < overlay.size(); ++i)
- {
- sum_pts += overlay[i].p1;
- sum_pts += overlay[i].p2;
- max_pts.x() = std::max(overlay[i].p1.x(), max_pts.x());
- max_pts.x() = std::max(overlay[i].p2.x(), max_pts.x());
- max_pts.y() = std::max(overlay[i].p1.y(), max_pts.y());
- max_pts.y() = std::max(overlay[i].p2.y(), max_pts.y());
- max_pts.z() = std::max(overlay[i].p1.z(), max_pts.z());
- max_pts.z() = std::max(overlay[i].p2.z(), max_pts.z());
- }
-
- tform = camera_transform(max_pts,
- sum_pts/(overlay_lines.size()*2+overlay_dots.size()),
- vector<double>(0,0,1),
- tform.get_camera_field_of_view(),
- std::min(rect.width(),rect.height()));
-
-
- // make the parent window redraw us now that we changed the overlay
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- add_overlay (
- const std::vector<overlay_dot>& overlay
- )
- {
- auto_mutex M(m);
- if (overlay.size() == 0)
- return;
-
- for (unsigned long i = 0; i < overlay.size(); ++i)
- {
- overlay_dots.push_back(overlay[i]);
-
- sum_pts += overlay[i].p;
- max_pts.x() = std::max(overlay[i].p.x(), max_pts.x());
- max_pts.y() = std::max(overlay[i].p.y(), max_pts.y());
- max_pts.z() = std::max(overlay[i].p.z(), max_pts.z());
- }
-
- tform = camera_transform(max_pts,
- sum_pts/(overlay_lines.size()*2+overlay_dots.size()),
- vector<double>(0,0,1),
- tform.get_camera_field_of_view(),
- std::min(rect.width(),rect.height()));
-
-
- // make the parent window redraw us now that we changed the overlay
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- clear_overlay (
- )
- {
- auto_mutex lock(m);
- overlay_dots.clear();
- overlay_lines.clear();
- sum_pts = vector<double>();
- max_pts = vector<double>(-std::numeric_limits<double>::infinity(),
- -std::numeric_limits<double>::infinity(),
- -std::numeric_limits<double>::infinity());
-
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- set_dot_double_clicked_handler (
- const any_function<void(const vector<double>&)>& event_handler_
- )
- {
- auto_mutex M(m);
- dot_clicked_event_handler = event_handler_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- draw (
- const canvas& c
- ) const
- {
- if (depth.nr() < (long)c.height() || depth.nc() < (long)c.width())
- depth.set_size(c.height(), c.width());
- assign_all_pixels(depth, std::numeric_limits<float>::infinity());
-
- rectangle area = rect.intersect(c);
- fill_rect(c, area, 0);
- for (unsigned long i = 0; i < overlay_lines.size(); ++i)
- {
- draw_line(c, tform(overlay_lines[i].p1)+rect.tl_corner(),
- tform(overlay_lines[i].p2)+rect.tl_corner(),
- overlay_lines[i].color,
- area);
- }
- for (unsigned long i = 0; i < overlay_dots.size(); ++i)
- {
- double scale, distance;
- point p = tform(overlay_dots[i].p, scale, distance) + rect.tl_corner();
- if (area.contains(p) && depth[p.y()-c.top()][p.x()-c.left()] > distance)
- {
- depth[p.y()-c.top()][p.x()-c.left()] = distance;
- assign_pixel(c[p.y()-c.top()][p.x()-c.left()], overlay_dots[i].color);
- }
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- on_wheel_up (
- unsigned long //state
- )
- {
- if (rect.contains(lastx,lasty) == false || hidden || !enabled)
- return;
-
- const double alpha = 0.10;
- const vector<double> delta = alpha*(tform.get_camera_pos() - tform.get_camera_looking_at());
- tform = camera_transform(
- tform.get_camera_pos() - delta,
- tform.get_camera_looking_at(),
- tform.get_camera_up_direction(),
- tform.get_camera_field_of_view(),
- std::min(rect.width(),rect.height()));
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- on_wheel_down (
- unsigned long //state
- )
- {
- if (rect.contains(lastx,lasty) == false || hidden || !enabled)
- return;
-
- const double alpha = 0.10;
- const vector<double> delta = alpha*(tform.get_camera_pos() - tform.get_camera_looking_at());
- tform = camera_transform(
- tform.get_camera_pos() + delta,
- tform.get_camera_looking_at(),
- tform.get_camera_up_direction(),
- tform.get_camera_field_of_view(),
- std::min(rect.width(),rect.height()));
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- on_mouse_down (
- unsigned long btn,
- unsigned long, //state
- long x,
- long y,
- bool is_double_click
- )
- {
- if (btn == base_window::LEFT || btn == base_window::RIGHT)
- {
- last = point(x,y);
- }
- if (is_double_click && btn == base_window::LEFT && enabled && !hidden && overlay_dots.size() != 0)
- {
- double best_dist = std::numeric_limits<double>::infinity();
- unsigned long best_idx = 0;
- const dpoint pp(x,y);
- for (unsigned long i = 0; i < overlay_dots.size(); ++i)
- {
- dpoint p = tform(overlay_dots[i].p) + rect.tl_corner();
- double dist = length_squared(p-pp);
- if (dist < best_dist)
- {
- best_dist = dist;
- best_idx = i;
- }
- }
- if (dot_clicked_event_handler.is_set())
- dot_clicked_event_handler(overlay_dots[best_idx].p);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void perspective_display::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- if (!enabled || hidden)
- return;
-
- if (state == base_window::LEFT)
- {
- const point cur(x, y);
- dpoint delta = last-cur;
- last = cur;
-
- const vector<double> radius = tform.get_camera_pos()-tform.get_camera_looking_at();
- delta *= 2*pi*length(radius)/600.0;
- vector<double> tangent_x = tform.get_camera_up_direction().cross(radius).normalize();
- vector<double> tangent_y = radius.cross(tangent_x).normalize();
- vector<double> new_pos = tform.get_camera_pos() + tangent_x*delta.x() + tangent_y*-delta.y();
-
- // now make it have the correct radius relative to the looking at point.
- new_pos = (new_pos-tform.get_camera_looking_at()).normalize()*length(radius) + tform.get_camera_looking_at();
-
- tform = camera_transform(new_pos,
- tform.get_camera_looking_at(),
- tangent_y,
- tform.get_camera_field_of_view(),
- std::min(rect.width(),rect.height()));
- parent.invalidate_rectangle(rect);
- }
- else if (state == (base_window::LEFT|base_window::SHIFT) ||
- state == base_window::RIGHT)
- {
- const point cur(x, y);
- dpoint delta = last-cur;
- last = cur;
-
- const vector<double> radius = tform.get_camera_pos()-tform.get_camera_looking_at();
- delta *= 2*pi*length(radius)/600.0;
- vector<double> tangent_x = tform.get_camera_up_direction().cross(radius).normalize();
- vector<double> tangent_y = radius.cross(tangent_x).normalize();
-
- vector<double> offset = tangent_x*delta.x() + tangent_y*-delta.y();
-
-
- tform = camera_transform(
- tform.get_camera_pos()+offset,
- tform.get_camera_looking_at()+offset,
- tform.get_camera_up_direction(),
- tform.get_camera_field_of_view(),
- std::min(rect.width(),rect.height()));
- parent.invalidate_rectangle(rect);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// image_display member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- class image_display_functor
- {
- const std::string str;
- const member_function_pointer<const std::string&> mfp;
- public:
- image_display_functor (
- const std::string& str_,
- const member_function_pointer<const std::string&>& mfp_
- ) : str(str_),
- mfp(mfp_)
- {}
-
- void operator() (
- ) const { mfp(str); }
- };
- }
-
- image_display::
- image_display(
- drawable_window& w
- ):
- scrollable_region(w,KEYBOARD_EVENTS),
- zoom_in_scale(1),
- zoom_out_scale(1),
- drawing_rect(true),
- rect_is_selected(false),
- selected_rect(0),
- default_rect_color(255,0,0,255),
- parts_menu(w),
- part_width(100), // "parts" circles are drawn 1.0/part_width size on the screen relative to the size of the bounding rectangle.
- overlay_editing_enabled(true),
- highlight_timer(*this, &image_display::timer_event_unhighlight_rect),
- highlighted_rect(std::numeric_limits<unsigned long>::max()),
- holding_shift_key(false)
- {
- enable_mouse_drag();
-
- highlight_timer.set_delay_time(250);
- set_horizontal_scroll_increment(1);
- set_vertical_scroll_increment(1);
- set_horizontal_mouse_wheel_scroll_increment(30);
- set_vertical_mouse_wheel_scroll_increment(30);
-
- parts_menu.disable();
-
-
- enable_events();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- on_part_add (
- const std::string& part_name
- )
- {
- if (!rect_is_selected)
- return;
-
- const point loc = last_right_click_pos;
-
- // Transform loc from gui window space into the space used by the overlay
- // rectangles (i.e. relative to the raw image)
- const point origin(total_rect().tl_corner());
- point c1 = loc - origin;
- if (zoom_in_scale != 1)
- {
- c1 = c1/(double)zoom_in_scale;
- }
- else if (zoom_out_scale != 1)
- {
- c1 = c1*(double)zoom_out_scale;
- }
-
- overlay_rects[selected_rect].parts[part_name] = c1;
- parent.invalidate_rectangle(rect);
-
- if (event_handler.is_set())
- event_handler();
- }
-
-// ----------------------------------------------------------------------------------------
-
- image_display::
- ~image_display(
- )
- {
- highlight_timer.stop_and_wait();
- disable_events();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle image_display::
- get_image_display_rect (
- ) const
- {
- if (zoom_in_scale != 1)
- {
- return rectangle(0,0, img.nc()*zoom_in_scale-1, img.nr()*zoom_in_scale-1);
- }
- else if (zoom_out_scale != 1)
- {
- return rectangle(0,0, img.nc()/zoom_out_scale-1, img.nr()/zoom_out_scale-1);
- }
- else
- {
- return dlib::get_rect(img);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- add_overlay (
- const overlay_rect& overlay
- )
- {
- auto_mutex M(m);
- // push this new overlay into our overlay vector
- overlay_rects.push_back(overlay);
-
- // make the parent window redraw us now that we changed the overlay
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- add_overlay (
- const overlay_line& overlay
- )
- {
- auto_mutex M(m);
-
- // push this new overlay into our overlay vector
- overlay_lines.push_back(overlay);
-
- // make the parent window redraw us now that we changed the overlay
- parent.invalidate_rectangle(get_rect_on_screen(rectangle(overlay.p1, overlay.p2)));
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- add_overlay (
- const overlay_circle& overlay
- )
- {
- auto_mutex M(m);
-
- // push this new overlay into our overlay vector
- overlay_circles.push_back(overlay);
-
- // make the parent window redraw us now that we changed the overlay
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- add_overlay (
- const std::vector<overlay_rect>& overlay
- )
- {
- auto_mutex M(m);
-
- // push this new overlay into our overlay vector
- overlay_rects.insert(overlay_rects.end(), overlay.begin(), overlay.end());
-
- // make the parent window redraw us now that we changed the overlay
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- add_overlay (
- const std::vector<overlay_line>& overlay
- )
- {
- auto_mutex M(m);
-
- // push this new overlay into our overlay vector
- overlay_lines.insert(overlay_lines.end(), overlay.begin(), overlay.end());
-
- // make the parent window redraw us now that we changed the overlay
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- add_overlay (
- const std::vector<overlay_circle>& overlay
- )
- {
- auto_mutex M(m);
-
- // push this new overlay into our overlay vector
- overlay_circles.insert(overlay_circles.end(), overlay.begin(), overlay.end());
-
- // make the parent window redraw us now that we changed the overlay
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- clear_overlay (
- )
- {
- auto_mutex M(m);
- overlay_rects.clear();
- overlay_lines.clear();
- overlay_circles.clear();
- parent.invalidate_rectangle(rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle image_display::
- get_rect_on_screen (
- rectangle orect
- ) const
- {
- const point origin(total_rect().tl_corner());
- orect.left() = orect.left()*zoom_in_scale/zoom_out_scale;
- orect.top() = orect.top()*zoom_in_scale/zoom_out_scale;
- if (zoom_in_scale != 1)
- {
- // make it so the box surrounds the pixels when we zoom in.
- orect.right() = (orect.right()+1)*zoom_in_scale/zoom_out_scale;
- orect.bottom() = (orect.bottom()+1)*zoom_in_scale/zoom_out_scale;
- }
- else
- {
- orect.right() = orect.right()*zoom_in_scale/zoom_out_scale;
- orect.bottom() = orect.bottom()*zoom_in_scale/zoom_out_scale;
- }
-
- return translate_rect(orect, origin);
- }
-
-// ----------------------------------------------------------------------------------------
-
- rectangle image_display::
- get_rect_on_screen (
- unsigned long idx
- ) const
- {
- return get_rect_on_screen(overlay_rects[idx].rect);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- draw (
- const canvas& c
- ) const
- {
- scrollable_region::draw(c);
-
- rectangle area = display_rect().intersect(c);
- if (area.is_empty())
- return;
-
- const point origin(total_rect().tl_corner());
-
- // draw the image on the screen
- const double scale = zoom_out_scale/(double)zoom_in_scale;
- const rectangle img_area = total_rect().intersect(area);
- for (long row = img_area.top(); row <= img_area.bottom(); ++row)
- {
- const long rc = row-c.top();
- const long rimg = (row-origin.y())*scale;
- for (long col = img_area.left(); col <= img_area.right(); ++col)
- {
- assign_pixel(c[rc][col-c.left()],
- img[rimg][(col-origin.x())*scale]);
- }
- }
-
- // draw the mouse cross-hairs
- if (holding_shift_key && total_rect().contains(lastx,lasty) )
- {
- draw_line(c, point(lastx,-10000), point(lastx,100000),rgb_pixel(255,255,0), area);
- draw_line(c, point(-10000,lasty), point(100000,lasty),rgb_pixel(255,255,0), area);
- }
-
- // now draw all the overlay rectangles
- for (unsigned long i = 0; i < overlay_rects.size(); ++i)
- {
- const rectangle orect = get_rect_on_screen(i);
- rgb_alpha_pixel color = overlay_rects[i].color;
- // draw crossed out boxes slightly faded
- if (overlay_rects[i].crossed_out)
- color.alpha = 150;
-
- if (rect_is_selected && selected_rect == i)
- {
- draw_rectangle(c, orect, invert_pixel(color), area);
- }
- else if (highlighted_rect < overlay_rects.size() && highlighted_rect == i)
- {
- // Draw the rectangle wider and with a slightly different color that tapers
- // out at the edges of the line.
- hsi_pixel temp;
- assign_pixel(temp, 0);
- assign_pixel(temp, overlay_rects[i].color);
- temp.s = 255;
- temp.h = temp.h + 20;
- if (temp.i < 245)
- temp.i += 10;
- rgb_pixel p;
- assign_pixel(p, temp);
- rgb_alpha_pixel po, po2;
- assign_pixel(po, p);
- po.alpha = 160;
- po2 = po;
- po2.alpha = 90;
- draw_rectangle(c, grow_rect(orect,2), po2, area);
- draw_rectangle(c, grow_rect(orect,1), po, area);
- draw_rectangle(c, orect, p, area);
- draw_rectangle(c, shrink_rect(orect,1), po, area);
- draw_rectangle(c, shrink_rect(orect,2), po2, area);
- }
- else
- {
- draw_rectangle(c, orect, color, area);
- }
-
- if (overlay_rects[i].label.size() != 0)
- {
- // make a rectangle that is at the spot we want to draw our string
- rectangle r(orect.br_corner(), c.br_corner());
- mfont->draw_string(c, r, overlay_rects[i].label, color, 0,
- std::string::npos, area);
- }
-
-
- // draw circles for each "part" in this overlay rectangle.
- std::map<std::string,point>::const_iterator itr;
- for (itr = overlay_rects[i].parts.begin(); itr != overlay_rects[i].parts.end(); ++itr)
- {
- if (itr->second == OBJECT_PART_NOT_PRESENT)
- continue;
-
- const long part_size = (long)std::max(1.0,std::round(std::sqrt(orect.area())/part_width));
- rectangle temp = centered_rect(get_rect_on_screen(centered_rect(itr->second,1,1)), part_size, part_size);
-
- if (rect_is_selected && selected_rect == i &&
- selected_part_name.size() != 0 && selected_part_name == itr->first)
- {
- draw_circle(c, center(temp), temp.width(), invert_pixel(color), area);
- }
- else
- {
- draw_circle(c, center(temp), temp.width(), color, area);
- }
-
- // make a rectangle that is at the spot we want to draw our string
- rectangle r((temp.br_corner() + temp.bl_corner())/2,
- c.br_corner());
- mfont->draw_string(c, r, itr->first, color, 0,
- std::string::npos, area);
- }
-
- if (overlay_rects[i].crossed_out)
- {
- if (rect_is_selected && selected_rect == i)
- {
- draw_line(c, orect.tl_corner(), orect.br_corner(),invert_pixel(color), area);
- draw_line(c, orect.bl_corner(), orect.tr_corner(),invert_pixel(color), area);
- }
- else
- {
- draw_line(c, orect.tl_corner(), orect.br_corner(),color, area);
- draw_line(c, orect.bl_corner(), orect.tr_corner(),color, area);
- }
- }
- }
-
- // now draw all the overlay lines
- for (unsigned long i = 0; i < overlay_lines.size(); ++i)
- {
- draw_line(c,
- zoom_in_scale*overlay_lines[i].p1/zoom_out_scale + origin,
- zoom_in_scale*overlay_lines[i].p2/zoom_out_scale + origin,
- overlay_lines[i].color, area);
- }
-
- // now draw all the overlay circles
- for (unsigned long i = 0; i < overlay_circles.size(); ++i)
- {
- const point center = zoom_in_scale*overlay_circles[i].center/zoom_out_scale + origin;
- const int radius = zoom_in_scale*overlay_circles[i].radius/zoom_out_scale;
- draw_circle(c,
- center,
- radius,
- overlay_circles[i].color, area);
-
- if (overlay_circles[i].label.size() != 0)
- {
- const point temp = center + point(0,radius);
-
- // make a rectangle that is at the spot we want to draw our string
- rectangle r(temp, c.br_corner());
- mfont->draw_string(c, r, overlay_circles[i].label, overlay_circles[i].color, 0,
- std::string::npos, area);
- }
- }
-
- if (drawing_rect)
- draw_rectangle(c, rect_to_draw, invert_pixel(default_rect_color), area);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- )
- {
- scrollable_region::on_keydown(key,is_printable, state);
-
- if (!is_printable && key==base_window::KEY_SHIFT)
- {
- if (!holding_shift_key)
- {
- holding_shift_key = true;
- parent.invalidate_rectangle(rect);
- }
- }
- else if (holding_shift_key)
- {
- holding_shift_key = false;
- parent.invalidate_rectangle(rect);
- }
-
- if (!is_printable && !hidden && enabled && rect_is_selected &&
- (key == base_window::KEY_BACKSPACE || key == base_window::KEY_DELETE))
- {
- moving_overlay = false;
- rect_is_selected = false;
- parts_menu.disable();
- if (selected_part_name.size() == 0)
- overlay_rects.erase(overlay_rects.begin() + selected_rect);
- else
- overlay_rects[selected_rect].parts.erase(selected_part_name);
- parent.invalidate_rectangle(rect);
-
- if (event_handler.is_set())
- event_handler();
- }
-
- if (!hidden && enabled && rect_is_selected &&
- ((is_printable && key == 'i') || (!is_printable && key==base_window::KEY_END)))
- {
- overlay_rects[selected_rect].crossed_out = !overlay_rects[selected_rect].crossed_out;
- parent.invalidate_rectangle(rect);
-
- if (event_handler.is_set())
- event_handler();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- add_labelable_part_name (
- const std::string& name
- )
- {
- auto_mutex lock(m);
- if (part_names.insert(name).second)
- {
- member_function_pointer<const std::string&> mfp;
- mfp.set(*this,&image_display::on_part_add);
- parts_menu.menu().add_menu_item(menu_item_text("Add " + name,impl::image_display_functor(name,mfp)));
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- clear_labelable_part_names (
- )
- {
- auto_mutex lock(m);
- part_names.clear();
- parts_menu.menu().clear();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- )
- {
- scrollable_region::on_mouse_down(btn, state, x, y, is_double_click);
-
- if (state&base_window::SHIFT)
- {
- holding_shift_key = true;
- }
- else if (holding_shift_key)
- {
- holding_shift_key = false;
- parent.invalidate_rectangle(rect);
- }
-
- if (rect.contains(x,y) == false || hidden || !enabled)
- return;
-
- if (image_clicked_handler.is_set())
- {
- const point origin(total_rect().tl_corner());
- point p(x,y);
- p -= origin;
- if (zoom_in_scale != 1)
- p = p/zoom_in_scale;
- else if (zoom_out_scale != 1)
- p = p*zoom_out_scale;
-
- if (dlib::get_rect(img).contains(p))
- image_clicked_handler(p, is_double_click, btn);
- }
-
- if (!overlay_editing_enabled)
- return;
-
- if (btn == base_window::RIGHT && (state&base_window::SHIFT))
- {
- const bool rect_was_selected = rect_is_selected;
- rect_is_selected = false;
- parts_menu.disable();
-
- long best_dist = std::numeric_limits<long>::max();
- long best_idx = 0;
- std::string best_part;
-
- // check if this click landed on any of the overlay rectangles
- for (unsigned long i = 0; i < overlay_rects.size(); ++i)
- {
- const rectangle orect = get_rect_on_screen(i);
-
- const long dist = distance_to_rect_edge(orect, point(x,y));
-
- if (dist < best_dist)
- {
- best_dist = dist;
- best_idx = i;
- best_part.clear();
- }
-
- std::map<std::string,point>::const_iterator itr;
- for (itr = overlay_rects[i].parts.begin(); itr != overlay_rects[i].parts.end(); ++itr)
- {
- if (itr->second == OBJECT_PART_NOT_PRESENT)
- continue;
-
- const long part_size = (long)std::max(1.0,std::round(std::sqrt(orect.area())/part_width));
- rectangle temp = centered_rect(get_rect_on_screen(centered_rect(itr->second,1,1)), part_size, part_size);
- point c = center(temp);
-
- // distance from edge of part circle
- const long dist = static_cast<long>(std::abs(length(c - point(x,y)) + 0.5 - temp.width()));
- if (dist < best_dist)
- {
- best_idx = i;
- best_dist = dist;
- best_part = itr->first;
- }
- }
- }
-
-
- if (best_dist < 13)
- {
- moving_overlay = true;
- moving_rect = best_idx;
- moving_part_name = best_part;
- // If we are moving one of the sides of the rectangle rather than one of
- // the parts circles then we need to figure out which side of the rectangle
- // we are moving.
- if (best_part.size() == 0)
- {
- // which side is the click closest to?
- const rectangle orect = get_rect_on_screen(best_idx);
- const point p = nearest_point(orect,point(x,y));
- long dist_left = std::abs(p.x()-orect.left());
- long dist_top = std::abs(p.y()-orect.top());
- long dist_right = std::abs(p.x()-orect.right());
- long dist_bottom = std::abs(p.y()-orect.bottom());
- long min_val = std::min(std::min(dist_left,dist_right),std::min(dist_top,dist_bottom));
- if (dist_left == min_val)
- moving_what = MOVING_RECT_LEFT;
- else if (dist_top == min_val)
- moving_what = MOVING_RECT_TOP;
- else if (dist_right == min_val)
- moving_what = MOVING_RECT_RIGHT;
- else
- moving_what = MOVING_RECT_BOTTOM;
- }
- else
- {
- moving_what = MOVING_PART;
- }
- // Do this to make the moving stuff snap to the mouse immediately.
- on_mouse_move(state|btn,x,y);
- }
-
- if (rect_was_selected)
- parent.invalidate_rectangle(rect);
-
- return;
- }
-
- if (btn == base_window::RIGHT && rect_is_selected)
- {
- last_right_click_pos = point(x,y);
- parts_menu.set_rect(rect);
- return;
- }
-
- if (btn == base_window::LEFT && (state&base_window::CONTROL) && !drawing_rect)
- {
- long best_dist = std::numeric_limits<long>::max();
- long best_idx = 0;
- // check if this click landed on any of the overlay rectangles
- for (unsigned long i = 0; i < overlay_rects.size(); ++i)
- {
- const rectangle orect = get_rect_on_screen(i);
- const long dist = distance_to_rect_edge(orect, point(x,y));
-
- if (dist < best_dist)
- {
- best_dist = dist;
- best_idx = i;
- }
- }
- if (best_dist < 13)
- {
- overlay_rects[best_idx].label = default_rect_label;
- overlay_rects[best_idx].color = default_rect_color;
- highlighted_rect = best_idx;
- highlight_timer.stop();
- highlight_timer.start();
- if (event_handler.is_set())
- event_handler();
- parent.invalidate_rectangle(rect);
- }
- return;
- }
-
-
- if (!is_double_click && btn == base_window::LEFT && (state&base_window::SHIFT))
- {
- drawing_rect = true;
- rect_anchor = point(x,y);
-
- if (rect_is_selected)
- {
- rect_is_selected = false;
- parts_menu.disable();
- parent.invalidate_rectangle(rect);
- }
- }
- else if (drawing_rect)
- {
- if (rect_is_selected)
- {
- rect_is_selected = false;
- parts_menu.disable();
- }
-
- drawing_rect = false;
- parent.invalidate_rectangle(rect);
- }
- else if (is_double_click)
- {
- const bool rect_was_selected = rect_is_selected;
- rect_is_selected = false;
- parts_menu.disable();
-
- long best_dist = std::numeric_limits<long>::max();
- long best_idx = 0;
- std::string best_part;
-
- // check if this click landed on any of the overlay rectangles
- for (unsigned long i = 0; i < overlay_rects.size(); ++i)
- {
- const rectangle orect = get_rect_on_screen(i);
-
- const long dist = distance_to_rect_edge(orect, point(x,y));
-
- if (dist < best_dist)
- {
- best_dist = dist;
- best_idx = i;
- best_part.clear();
- }
-
- std::map<std::string,point>::const_iterator itr;
- for (itr = overlay_rects[i].parts.begin(); itr != overlay_rects[i].parts.end(); ++itr)
- {
- if (itr->second == OBJECT_PART_NOT_PRESENT)
- continue;
-
- const long part_size = (long)std::max(1.0,std::round(std::sqrt(orect.area())/part_width));
- rectangle temp = centered_rect(get_rect_on_screen(centered_rect(itr->second,1,1)), part_size, part_size);
- point c = center(temp);
-
- // distance from edge of part circle
- const long dist = static_cast<long>(std::abs(length(c - point(x,y)) + 0.5 - temp.width()));
- if (dist < best_dist)
- {
- best_idx = i;
- best_dist = dist;
- best_part = itr->first;
- }
- }
- }
-
-
- if (best_dist < 13)
- {
- rect_is_selected = true;
- if (part_names.size() != 0)
- parts_menu.enable();
- selected_rect = best_idx;
- selected_part_name = best_part;
- if (orect_selected_event_handler.is_set())
- orect_selected_event_handler(overlay_rects[best_idx]);
- }
-
- if (rect_is_selected || rect_was_selected)
- parent.invalidate_rectangle(rect);
- }
- else if (rect_is_selected)
- {
- rect_is_selected = false;
- parts_menu.disable();
- parent.invalidate_rectangle(rect);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- std::vector<image_display::overlay_rect> image_display::
- get_overlay_rects (
- ) const
- {
- auto_mutex lock(m);
- return overlay_rects;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- set_default_overlay_rect_label (
- const std::string& label
- )
- {
- auto_mutex lock(m);
- default_rect_label = label;
- }
-
-// ----------------------------------------------------------------------------------------
-
- std::string image_display::
- get_default_overlay_rect_label (
- ) const
- {
- auto_mutex lock(m);
- return default_rect_label;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- set_default_overlay_rect_color (
- const rgb_alpha_pixel& color
- )
- {
- auto_mutex lock(m);
- default_rect_color = color;
- }
-
-// ----------------------------------------------------------------------------------------
-
- rgb_alpha_pixel image_display::
- get_default_overlay_rect_color (
- ) const
- {
- auto_mutex lock(m);
- return default_rect_color;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- )
- {
- scrollable_region::on_mouse_up(btn,state,x,y);
-
- if (state&base_window::SHIFT)
- {
- holding_shift_key = true;
- }
- else if (holding_shift_key)
- {
- holding_shift_key = false;
- parent.invalidate_rectangle(rect);
- }
-
- if (drawing_rect && btn == base_window::LEFT && (state&base_window::SHIFT) &&
- !hidden && enabled)
- {
- const point origin(total_rect().tl_corner());
- point c1 = point(x,y) - origin;
- point c2 = rect_anchor - origin;
-
- if (zoom_in_scale != 1)
- {
- c1 = c1/(double)zoom_in_scale;
- c2 = c2/(double)zoom_in_scale;
- }
- else if (zoom_out_scale != 1)
- {
- c1 = c1*(double)zoom_out_scale;
- c2 = c2*(double)zoom_out_scale;
- }
-
- rectangle new_rect(c1,c2);
- if (zoom_in_scale != 1)
- {
- // When we are zoomed in we adjust the rectangles a little so they
- // are drown surrounding the pixels inside the rect. This adjustment
- // is necessary to make this code consistent with this goal.
- new_rect.right() -= 1;
- new_rect.bottom() -= 1;
- }
-
-
- if (new_rect.width() > 0 && new_rect.height() > 0)
- {
- add_overlay(overlay_rect(new_rect, default_rect_color, default_rect_label));
-
- if (event_handler.is_set())
- event_handler();
- }
- }
-
- if (drawing_rect)
- {
- drawing_rect = false;
- parent.invalidate_rectangle(rect);
- }
- if (moving_overlay)
- {
- moving_overlay = false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- scrollable_region::on_mouse_move(state,x,y);
-
- if (enabled && !hidden)
- {
- if (holding_shift_key)
- parent.invalidate_rectangle(rect);
-
- if (state&base_window::SHIFT)
- holding_shift_key = true;
- else if (holding_shift_key)
- holding_shift_key = false;
- }
-
- if (drawing_rect)
- {
- if ((state&base_window::LEFT) && (state&base_window::SHIFT) && !hidden && enabled)
- {
- rectangle new_rect(point(x,y), rect_anchor);
- parent.invalidate_rectangle(new_rect + rect_to_draw);
- rect_to_draw = new_rect;
- }
- else
- {
- drawing_rect = false;
- parent.invalidate_rectangle(rect);
- }
- moving_overlay = false;
- }
- else if (moving_overlay)
- {
- if ((state&base_window::RIGHT) && (state&base_window::SHIFT) && !hidden && enabled)
- {
- // map point(x,y) into the image coordinate space.
- point p = point(x,y) - total_rect().tl_corner();
- if (zoom_in_scale != 1)
- {
- if (moving_what == MOVING_PART)
- p = p/(double)zoom_in_scale-dpoint(0.5,0.5);
- else
- p = p/(double)zoom_in_scale;
- }
- else if (zoom_out_scale != 1)
- {
- p = p*(double)zoom_out_scale;
- }
-
-
- if (moving_what == MOVING_PART)
- {
- if (overlay_rects[moving_rect].parts[moving_part_name] != p)
- {
- overlay_rects[moving_rect].parts[moving_part_name] = p;
- parent.invalidate_rectangle(rect);
- if (event_handler.is_set())
- event_handler();
- }
- }
- else
- {
- rectangle original = overlay_rects[moving_rect].rect;
- if (moving_what == MOVING_RECT_LEFT)
- overlay_rects[moving_rect].rect.left() = std::min(p.x(), overlay_rects[moving_rect].rect.right());
- else if (moving_what == MOVING_RECT_RIGHT)
- overlay_rects[moving_rect].rect.right() = std::max(p.x()-1, overlay_rects[moving_rect].rect.left());
- else if (moving_what == MOVING_RECT_TOP)
- overlay_rects[moving_rect].rect.top() = std::min(p.y(), overlay_rects[moving_rect].rect.bottom());
- else
- overlay_rects[moving_rect].rect.bottom() = std::max(p.y()-1, overlay_rects[moving_rect].rect.top());
-
- if (original != overlay_rects[moving_rect].rect)
- {
- parent.invalidate_rectangle(rect);
- if (event_handler.is_set())
- event_handler();
- }
- }
- }
- else
- {
- moving_overlay = false;
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- on_wheel_up (
- unsigned long state
- )
- {
- // disable mouse wheel if the user is drawing a rectangle
- if (drawing_rect)
- return;
-
- // if CONTROL is not being held down
- if ((state & base_window::CONTROL) == 0)
- {
- scrollable_region::on_wheel_up(state);
- return;
- }
-
- if (rect.contains(lastx,lasty) == false || hidden || !enabled)
- return;
-
-
- if (zoom_in_scale < 100 && zoom_out_scale == 1)
- {
- const point mouse_loc(lastx, lasty);
- // the pixel in img that the mouse is over
- const point pix_loc = (mouse_loc - total_rect().tl_corner())/zoom_in_scale;
-
- zoom_in_scale = zoom_in_scale*10/9 + 1;
-
- set_total_rect_size(img.nc()*zoom_in_scale, img.nr()*zoom_in_scale);
-
- // make is to the pixel under the mouse doesn't move while we zoom
- const point delta = total_rect().tl_corner() - (mouse_loc - pix_loc*zoom_in_scale);
- scroll_to_rect(translate_rect(display_rect(), delta));
- }
- else if (zoom_out_scale != 1)
- {
- const point mouse_loc(lastx, lasty);
- // the pixel in img that the mouse is over
- const point pix_loc = (mouse_loc - total_rect().tl_corner())*zoom_out_scale;
-
- zoom_out_scale = zoom_out_scale*9/10;
- if (zoom_out_scale == 0)
- zoom_out_scale = 1;
-
- set_total_rect_size(img.nc()/zoom_out_scale, img.nr()/zoom_out_scale);
-
- // make is to the pixel under the mouse doesn't move while we zoom
- const point delta = total_rect().tl_corner() - (mouse_loc - pix_loc/zoom_out_scale);
- scroll_to_rect(translate_rect(display_rect(), delta));
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_display::
- on_wheel_down (
- unsigned long state
- )
- {
- // disable mouse wheel if the user is drawing a rectangle
- if (drawing_rect)
- return;
-
- // if CONTROL is not being held down
- if ((state & base_window::CONTROL) == 0)
- {
- scrollable_region::on_wheel_down(state);
- return;
- }
-
- if (rect.contains(lastx,lasty) == false || hidden || !enabled)
- return;
-
-
- if (zoom_in_scale != 1)
- {
- const point mouse_loc(lastx, lasty);
- // the pixel in img that the mouse is over
- const point pix_loc = (mouse_loc - total_rect().tl_corner())/zoom_in_scale;
-
- zoom_in_scale = zoom_in_scale*9/10;
- if (zoom_in_scale == 0)
- zoom_in_scale = 1;
-
- set_total_rect_size(img.nc()*zoom_in_scale, img.nr()*zoom_in_scale);
-
- // make is to the pixel under the mouse doesn't move while we zoom
- const point delta = total_rect().tl_corner() - (mouse_loc - pix_loc*zoom_in_scale);
- scroll_to_rect(translate_rect(display_rect(), delta));
- }
- else if (std::max(img.nr(), img.nc())/zoom_out_scale > 10)
- {
- const point mouse_loc(lastx, lasty);
- // the pixel in img that the mouse is over
- const point pix_loc = (mouse_loc - total_rect().tl_corner())*zoom_out_scale;
-
- zoom_out_scale = zoom_out_scale*10/9 + 1;
-
- set_total_rect_size(img.nc()/zoom_out_scale, img.nr()/zoom_out_scale);
-
- // make is to the pixel under the mouse doesn't move while we zoom
- const point delta = total_rect().tl_corner() - (mouse_loc - pix_loc/zoom_out_scale);
- scroll_to_rect(translate_rect(display_rect(), delta));
- }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// image_window member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- image_window::
- image_window(
- ) :
- gui_img(*this),
- window_has_closed(false),
- have_last_click(false),
- mouse_btn(0),
- clicked_signaler(this->wm),
- tie_input_events(false)
- {
-
- gui_img.set_image_clicked_handler(*this, &image_window::on_image_clicked);
- gui_img.disable_overlay_editing();
- // show this window on the screen
- show();
- }
-
-// ----------------------------------------------------------------------------------------
-
- image_window::
- ~image_window(
- )
- {
- // You should always call close_window() in the destructor of window
- // objects to ensure that no events will be sent to this window while
- // it is being destructed.
- close_window();
- }
-
-// ----------------------------------------------------------------------------------------
-
- base_window::on_close_return_code image_window::
- on_window_close(
- )
- {
- window_has_closed = true;
- clicked_signaler.broadcast();
- return base_window::CLOSE_WINDOW;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool image_window::
- get_next_keypress (
- unsigned long& key,
- bool& is_printable,
- unsigned long& state
- )
- {
- auto_mutex lock(wm);
- while (have_last_keypress == false && !window_has_closed &&
- (have_last_click == false || !tie_input_events))
- {
- clicked_signaler.wait();
- }
-
- if (window_has_closed)
- return false;
-
- if (have_last_keypress)
- {
- // Mark that we are taking the key click so the next call to get_next_keypress()
- // will have to wait for another click.
- have_last_keypress = false;
- key = next_key;
- is_printable = next_is_printable;
- state = next_state;
- return true;
- }
- else
- {
- key = 0;
- is_printable = true;
- return false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- )
- {
- dlib::drawable_window::on_keydown(key,is_printable,state);
-
- have_last_keypress = true;
- next_key = key;
- next_is_printable = is_printable;
- next_state = state;
- clicked_signaler.signal();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- tie_events (
- )
- {
- auto_mutex lock(wm);
- tie_input_events = true;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- untie_events (
- )
- {
- auto_mutex lock(wm);
- tie_input_events = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool image_window::
- events_tied (
- ) const
- {
- auto_mutex lock(wm);
- return tie_input_events;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool image_window::
- get_next_double_click (
- point& p,
- unsigned long& mouse_button
- )
- {
- p = point(-1,-1);
-
- auto_mutex lock(wm);
- while (have_last_click == false && !window_has_closed &&
- (have_last_keypress==false || !tie_input_events))
- {
- clicked_signaler.wait();
- }
-
- if (window_has_closed)
- return false;
-
- if (have_last_click)
- {
- // Mark that we are taking the point click so the next call to
- // get_next_double_click() will have to wait for another click.
- have_last_click = false;
- mouse_button = mouse_btn;
- p = last_clicked_point;
- return true;
- }
- else
- {
- return false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- on_image_clicked (
- const point& p,
- bool is_double_click,
- unsigned long btn
- )
- {
- if (is_double_click)
- {
- have_last_click = true;
- last_clicked_point = p;
- mouse_btn = btn;
- clicked_signaler.signal();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- add_overlay (
- const overlay_rect& overlay
- )
- {
- gui_img.add_overlay(overlay);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- add_overlay (
- const overlay_line& overlay
- )
- {
- gui_img.add_overlay(overlay);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- add_overlay (
- const overlay_circle& overlay
- )
- {
- gui_img.add_overlay(overlay);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- add_overlay (
- const std::vector<overlay_rect>& overlay
- )
- {
- gui_img.add_overlay(overlay);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- add_overlay (
- const std::vector<overlay_line>& overlay
- )
- {
- gui_img.add_overlay(overlay);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- add_overlay (
- const std::vector<overlay_circle>& overlay
- )
- {
- gui_img.add_overlay(overlay);
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- clear_overlay (
- )
- {
- gui_img.clear_overlay();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void image_window::
- on_window_resized(
- )
- {
- drawable_window::on_window_resized();
- unsigned long width, height;
- get_size(width,height);
- gui_img.set_size(width, height);
-
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_WIDGETs_CPP_
-
diff --git a/ml/dlib/dlib/gui_widgets/widgets.h b/ml/dlib/dlib/gui_widgets/widgets.h
deleted file mode 100644
index 305d7dc00..000000000
--- a/ml/dlib/dlib/gui_widgets/widgets.h
+++ /dev/null
@@ -1,4165 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-
-#ifndef DLIB_WIDGETs_
-#define DLIB_WIDGETs_
-
-#include <cctype>
-#include <memory>
-#include <set>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "../algs.h"
-#include "widgets_abstract.h"
-#include "drawable.h"
-#include "../gui_core.h"
-#include "fonts.h"
-#include "../timer.h"
-#include "base_widgets.h"
-#include "../member_function_pointer.h"
-#include "../array.h"
-#include "../array2d.h"
-#include "../sequence.h"
-#include "../dir_nav.h"
-#include "../queue.h"
-#include "style.h"
-#include "../string.h"
-#include "../misc_api.h"
-#include "../any.h"
-#include "../image_processing/full_object_detection.h"
-
-#ifdef _MSC_VER
-// This #pragma directive is also located in the algs.h file but for whatever
-// reason visual studio 9 just ignores it when it is only there.
-
-// this is to disable the "'this' : used in base member initializer list"
-// warning you get from some of the GUI objects since all the objects
-// require that their parent class be passed into their constructor.
-// In this case though it is totally safe so it is ok to disable this warning.
-#pragma warning(disable : 4355)
-#endif
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class label
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class label : public drawable
- {
- public:
- label(
- drawable_window& w
- ) :
- drawable(w),
- text_color_(0,0,0)
- {
- enable_events();
- }
-
- ~label()
- { disable_events(); parent.invalidate_rectangle(rect); }
-
- void set_text (
- const std::string& text
- );
-
- void set_text (
- const std::wstring& text
- );
-
- void set_text (
- const dlib::ustring& text
- );
-
- const std::string text (
- ) const;
-
- const std::wstring wtext (
- ) const;
-
- const dlib::ustring utext (
- ) const;
-
- void set_text_color (
- const rgb_pixel color
- );
-
- const rgb_pixel text_color (
- ) const;
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- private:
- dlib::ustring text_;
- rgb_pixel text_color_;
-
-
- // restricted functions
- label(label&); // copy constructor
- label& operator=(label&); // assignment operator
-
- protected:
-
- void draw (
- const canvas& c
- ) const;
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class toggle_button
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class toggle_button : public button_action
- {
- /*!
- INITIAL VALUE
- - checked == false
-
- CONVENTION
- - is_checked() == checked
- !*/
-
- public:
-
- toggle_button(
- drawable_window& w
- ) :
- button_action(w),
- btn_tooltip(w),
- checked(false)
- {
- style.reset(new toggle_button_style_default());
- enable_events();
- }
-
- ~toggle_button() { disable_events(); parent.invalidate_rectangle(rect); }
-
- void set_name (
- const std::string& name
- );
-
- void set_name (
- const std::wstring& name
- );
-
- void set_name (
- const dlib::ustring& name
- );
-
- void set_size (
- unsigned long width_,
- unsigned long height_
- );
-
- void set_tooltip_text (
- const std::string& text
- );
-
- void set_tooltip_text (
- const std::wstring& text
- );
-
- void set_tooltip_text (
- const ustring& text
- );
-
- const std::string tooltip_text (
- ) const;
-
- const std::wstring tooltip_wtext (
- ) const;
-
- const dlib::ustring tooltip_utext (
- ) const;
-
- bool is_checked (
- ) const;
-
- const std::string name (
- ) const;
-
- const std::wstring wname (
- ) const;
-
- const dlib::ustring uname (
- ) const;
-
- void set_checked (
- );
-
- void set_unchecked (
- );
-
- void show (
- );
-
- void hide (
- );
-
- void enable (
- );
-
- void disable (
- );
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- void set_pos (
- long x,
- long y
- );
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- )
- {
- auto_mutex M(m);
- style.reset(new style_type(style_));
- rect = move_rect(style->get_min_size(name_,*mfont), rect.left(), rect.top());
- parent.invalidate_rectangle(rect);
- }
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler_)()
- )
- {
- auto_mutex M(m);
- event_handler = make_mfp(object,event_handler_);
- event_handler_self.clear();
- }
-
- void set_click_handler (
- const any_function<void()>& event_handler_
- )
- {
- auto_mutex M(m);
- event_handler = event_handler_;
- event_handler_self.clear();
- }
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler_)(toggle_button&)
- )
- {
- auto_mutex M(m);
- event_handler_self = make_mfp(object,event_handler_);
- event_handler.clear();
- }
-
- void set_sourced_click_handler (
- const any_function<void(toggle_button&)>& event_handler_
- )
- {
- auto_mutex M(m);
- event_handler_self = event_handler_;
- event_handler.clear();
- }
-
- private:
-
- // restricted functions
- toggle_button(toggle_button&); // copy constructor
- toggle_button& operator=(toggle_button&); // assignment operator
-
- dlib::ustring name_;
- tooltip btn_tooltip;
- bool checked;
-
- any_function<void()> event_handler;
- any_function<void(toggle_button&)> event_handler_self;
-
- std::unique_ptr<toggle_button_style> style;
-
- protected:
-
- void draw (
- const canvas& c
- ) const { style->draw_toggle_button(c,rect,enabled,*mfont,lastx,lasty,name_,is_depressed(),checked); }
-
- void on_button_up (
- bool mouse_over
- );
-
- void on_mouse_over (
- ){ if (style->redraw_on_mouse_over()) parent.invalidate_rectangle(rect); }
-
- void on_mouse_not_over (
- ){ if (style->redraw_on_mouse_over()) parent.invalidate_rectangle(rect); }
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class text_field
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_field : public drawable
- {
- /*!
- INITIAL VALUE
- text_color_ == rgb_pixel(0,0,0)
- bg_color_ == rgb_pixel(255,255,255)
- cursor_pos == 0
- text_width == 0
- text_ == ""
- has_focus == false
- cursor_visible == false
- recent_movement == false
- highlight_start == 0
- highlight_end == -1
- shift_pos == -1
- text_pos == 0
-
- CONVENTION
- - cursor_pos == the position of the cursor in the string text_. The
- cursor appears before the letter text_[cursor_pos]
- - cursor_x == the x coordinate of the cursor relative to the left side
- of rect. i.e. the number of pixels that separate the cursor from the
- left side of the text_field.
- - has_focus == true if this text field has keyboard input focus
- - cursor_visible == true if the cursor should be painted
- - text_ == text()
- - text_pos == the index of the first letter in text_ that appears in
- this text field.
- - text_width == the width of text_[text_pos] though text_[text.size()-1]
-
- - if (has_focus && the user has recently moved the cursor) then
- - recent_movement == true
- - else
- - recent_movement == false
-
- - if (highlight_start <= highlight_end) then
- - text[highlight_start] though text[highlight_end] should be
- highlighted
-
- - if (shift_pos != -1) then
- - has_focus == true
- - the shift key is being held down or the left mouse button is
- being held down.
- - shift_pos == the position of the cursor when the shift or mouse key
- was first pressed.
-
- - text_color() == text_color_
- - background_color() == bg_color_
- !*/
-
- public:
- text_field(
- drawable_window& w
- ) :
- drawable(w,MOUSE_CLICK | KEYBOARD_EVENTS | MOUSE_MOVE | STRING_PUT),
- text_color_(0,0,0),
- bg_color_(255,255,255),
- text_width(0),
- text_pos(0),
- recent_movement(false),
- has_focus(false),
- cursor_visible(false),
- cursor_pos(0),
- highlight_start(0),
- highlight_end(-1),
- shift_pos(-1),
- t(*this,&text_field::timer_action),
- right_click_menu(w)
- {
- style.reset(new text_field_style_default());
- rect.set_bottom(mfont->height()+ (style->get_padding(*mfont))*2);
- rect.set_right((style->get_padding(*mfont))*2);
- cursor_x = style->get_padding(*mfont);
-
- right_click_menu.menu().add_menu_item(menu_item_text("Cut",*this,&text_field::on_cut,'t'));
- right_click_menu.menu().add_menu_item(menu_item_text("Copy",*this,&text_field::on_copy,'C'));
- right_click_menu.menu().add_menu_item(menu_item_text("Paste",*this,&text_field::on_paste,'P'));
- right_click_menu.menu().add_menu_item(menu_item_text("Delete",*this,&text_field::on_delete_selected,'D'));
- right_click_menu.menu().add_menu_item(menu_item_separator());
- right_click_menu.menu().add_menu_item(menu_item_text("Select All",*this,&text_field::on_select_all,'A'));
-
- right_click_menu.set_rect(get_text_rect());
- enable_events();
-
- t.set_delay_time(500);
- }
-
- ~text_field (
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- t.stop_and_wait();
- }
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- )
- {
- auto_mutex M(m);
- style.reset(new style_type(style_));
- // call this just so that this widget redraws itself with the new style
- set_main_font(mfont);
- }
-
- void set_text (
- const std::string& text_
- );
-
- void set_text (
- const std::wstring& text_
- );
-
- void give_input_focus (
- );
-
- bool has_input_focus (
- ) const;
-
- void select_all_text (
- );
-
- void set_text (
- const dlib::ustring& text_
- );
-
- const std::string text (
- ) const;
-
- const std::wstring wtext (
- ) const;
-
- const dlib::ustring utext (
- ) const;
-
- void set_text_color (
- const rgb_pixel color
- );
-
- const rgb_pixel text_color (
- ) const;
-
- void set_background_color (
- const rgb_pixel color
- );
-
- const rgb_pixel background_color (
- ) const;
-
- void set_width (
- unsigned long width
- );
-
- void set_pos (
- long x,
- long y
- );
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- int next_free_user_event_number (
- ) const
- {
- return drawable::next_free_user_event_number()+1;
- }
-
- void disable (
- );
-
- void enable (
- );
-
- void hide (
- );
-
- void show (
- );
-
- template <
- typename T
- >
- void set_text_modified_handler (
- T& object,
- void (T::*event_handler)()
- )
- {
- auto_mutex M(m);
- text_modified_handler = make_mfp(object,event_handler);
- }
-
- template <
- typename T
- >
- void set_enter_key_handler (
- T& object,
- void (T::*event_handler)()
- )
- {
- auto_mutex M(m);
- enter_key_handler = make_mfp(object,event_handler);
- }
-
- void set_text_modified_handler (
- const any_function<void()>& event_handler
- )
- {
- auto_mutex M(m);
- text_modified_handler = event_handler;
- }
-
- void set_enter_key_handler (
- const any_function<void()>& event_handler
- )
- {
- auto_mutex M(m);
- enter_key_handler = event_handler;
- }
-
- template <
- typename T
- >
- void set_focus_lost_handler (
- T& object,
- void (T::*event_handler)()
- )
- {
- auto_mutex M(m);
- focus_lost_handler = make_mfp(object,event_handler);
- }
-
- void set_focus_lost_handler (
- const any_function<void()>& event_handler
- )
- {
- auto_mutex M(m);
- focus_lost_handler = event_handler;
- }
-
- private:
-
- void on_cut (
- );
-
- void on_copy (
- );
-
- void on_paste (
- );
-
- void on_select_all (
- );
-
- void on_delete_selected (
- );
-
- void on_text_is_selected (
- );
-
- void on_no_text_selected (
- );
-
- void on_user_event (
- int num
- )
- {
- // ignore this user event if it isn't for us
- if (num != drawable::next_free_user_event_number())
- return;
-
- if (recent_movement == false)
- {
- cursor_visible = !cursor_visible;
- parent.invalidate_rectangle(rect);
- }
- else
- {
- if (cursor_visible == false)
- {
- cursor_visible = true;
- parent.invalidate_rectangle(rect);
- }
- recent_movement = false;
- }
- }
-
- void timer_action (
- ) { parent.trigger_user_event(this,drawable::next_free_user_event_number()); }
- /*!
- ensures
- - flips the state of cursor_visible
- !*/
-
- void move_cursor (
- unsigned long pos
- );
- /*!
- requires
- - pos <= text_.size()
- ensures
- - moves the cursor to the position given by pos and moves the text
- in the text box if necessary
- - if the position changes then the parent window will be updated
- !*/
-
- rectangle get_text_rect (
- ) const;
- /*!
- ensures
- - returns the rectangle that should contain the text in this widget
- !*/
-
- dlib::ustring text_;
- rgb_pixel text_color_;
- rgb_pixel bg_color_;
-
- unsigned long text_width;
- unsigned long text_pos;
-
-
- bool recent_movement;
- bool has_focus;
- bool cursor_visible;
- long cursor_pos;
- unsigned long cursor_x;
-
- // this tells you what part of the text is highlighted
- long highlight_start;
- long highlight_end;
- long shift_pos;
- any_function<void()> text_modified_handler;
- any_function<void()> enter_key_handler;
- any_function<void()> focus_lost_handler;
-
- std::unique_ptr<text_field_style> style;
-
- timer<text_field> t;
-
- popup_menu_region right_click_menu;
-
- // restricted functions
- text_field(text_field&); // copy constructor
- text_field& operator=(text_field&); // assignment operator
-
-
- protected:
-
- void draw (
- const canvas& c
- ) const;
-
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- void on_string_put (
- const std::wstring &str
- );
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class text_box
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_box : public scrollable_region
- {
- /*!
- INITIAL VALUE
- text_color_ == rgb_pixel(0,0,0)
- bg_color_ == rgb_pixel(255,255,255)
- cursor_pos == 0
- text_ == ""
- has_focus == false
- cursor_visible == false
- recent_movement == false
- highlight_start == 0
- highlight_end == -1
- shift_pos == -1
-
- CONVENTION
- - cursor_pos == the position of the cursor in the string text_. The
- cursor appears before the letter text_[cursor_pos]
- - cursor_rect == The rectangle that should be drawn for the cursor.
- The position is relative to total_rect().
- - has_focus == true if this text field has keyboard input focus
- - cursor_visible == true if the cursor should be painted
- - text_ == text()
-
- - if (has_focus && the user has recently moved the cursor) then
- - recent_movement == true
- - else
- - recent_movement == false
-
- - if (highlight_start <= highlight_end) then
- - text[highlight_start] though text[highlight_end] should be
- highlighted
-
- - if (shift_pos != -1) then
- - has_focus == true
- - the shift key is being held down or the left mouse button is
- being held down.
- - shift_pos == the position of the cursor when the shift or mouse key
- was first pressed.
-
- - text_color() == text_color_
- - background_color() == bg_color_
- !*/
-
- public:
- text_box(
- drawable_window& w
- ) :
- scrollable_region(w,MOUSE_CLICK | KEYBOARD_EVENTS | MOUSE_MOVE | STRING_PUT),
- text_color_(0,0,0),
- bg_color_(255,255,255),
- recent_movement(false),
- has_focus(false),
- cursor_visible(false),
- cursor_pos(0),
- highlight_start(0),
- highlight_end(-1),
- shift_pos(-1),
- t(*this,&text_box::timer_action),
- right_click_menu(w)
- {
- style.reset(new text_box_style_default());
-
- const long padding = static_cast<long>(style->get_padding(*mfont));
- cursor_rect = mfont->compute_cursor_rect(rectangle(padding,padding,1000000,1000000), text_, 0);
-
- adjust_total_rect();
-
- set_vertical_mouse_wheel_scroll_increment(mfont->height());
- set_horizontal_mouse_wheel_scroll_increment(mfont->height());
-
- right_click_menu.menu().add_menu_item(menu_item_text("Cut",*this,&text_box::on_cut,'t'));
- right_click_menu.menu().add_menu_item(menu_item_text("Copy",*this,&text_box::on_copy,'C'));
- right_click_menu.menu().add_menu_item(menu_item_text("Paste",*this,&text_box::on_paste,'P'));
- right_click_menu.menu().add_menu_item(menu_item_text("Delete",*this,&text_box::on_delete_selected,'D'));
- right_click_menu.menu().add_menu_item(menu_item_separator());
- right_click_menu.menu().add_menu_item(menu_item_text("Select All",*this,&text_box::on_select_all,'A'));
-
- right_click_menu.set_rect(get_text_rect());
-
- set_size(100,100);
-
- enable_events();
-
- t.set_delay_time(500);
- }
-
- ~text_box (
- )
- {
- disable_events();
- parent.invalidate_rectangle(rect);
- t.stop_and_wait();
- }
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- )
- {
- auto_mutex M(m);
- style.reset(new style_type(style_));
-
- scrollable_region::set_style(style_.get_scrollable_region_style());
- // call this just so that this widget redraws itself with the new style
- set_main_font(mfont);
- }
-
- void set_text (
- const std::string& text_
- );
-
- void set_text (
- const std::wstring& text_
- );
-
- void set_text (
- const dlib::ustring& text_
- );
-
- const std::string text (
- ) const;
-
- const std::wstring wtext (
- ) const;
-
- const dlib::ustring utext (
- ) const;
-
- void set_text_color (
- const rgb_pixel color
- );
-
- const rgb_pixel text_color (
- ) const;
-
- void set_background_color (
- const rgb_pixel color
- );
-
- const rgb_pixel background_color (
- ) const;
-
- void set_size (
- unsigned long width,
- unsigned long height
- );
-
- void set_pos (
- long x,
- long y
- );
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- int next_free_user_event_number (
- ) const
- {
- return scrollable_region::next_free_user_event_number()+1;
- }
-
- void disable (
- );
-
- void enable (
- );
-
- void hide (
- );
-
- void show (
- );
-
- template <
- typename T
- >
- void set_text_modified_handler (
- T& object,
- void (T::*event_handler)()
- )
- {
- auto_mutex M(m);
- text_modified_handler = make_mfp(object,event_handler);
- }
-
- void set_text_modified_handler (
- const any_function<void()>& event_handler
- )
- {
- auto_mutex M(m);
- text_modified_handler = event_handler;
- }
-
- template <
- typename T
- >
- void set_enter_key_handler (
- T& object,
- void (T::*event_handler)()
- )
- {
- auto_mutex M(m);
- enter_key_handler = make_mfp(object,event_handler);
- }
-
- void set_enter_key_handler (
- const any_function<void()>& event_handler
- )
- {
- auto_mutex M(m);
- enter_key_handler = event_handler;
- }
-
- template <
- typename T
- >
- void set_focus_lost_handler (
- T& object,
- void (T::*event_handler)()
- )
- {
- auto_mutex M(m);
- focus_lost_handler = make_mfp(object,event_handler);
- }
-
- void set_focus_lost_handler (
- const any_function<void()>& event_handler
- )
- {
- auto_mutex M(m);
- focus_lost_handler = event_handler;
- }
-
- private:
-
- void on_cut (
- );
-
- void on_copy (
- );
-
- void on_paste (
- );
-
- void on_select_all (
- );
-
- void on_delete_selected (
- );
-
- void on_text_is_selected (
- );
-
- void on_no_text_selected (
- );
-
- void on_user_event (
- int num
- )
- {
- // ignore this user event if it isn't for us
- if (num != scrollable_region::next_free_user_event_number())
- return;
-
- if (recent_movement == false)
- {
- cursor_visible = !cursor_visible;
- parent.invalidate_rectangle(rect);
- }
- else
- {
- if (cursor_visible == false)
- {
- cursor_visible = true;
- parent.invalidate_rectangle(rect);
- }
- recent_movement = false;
- }
- }
-
- // The reason for using user actions here rather than just having the timer just call
- // what it needs directly is to avoid a potential deadlock during destruction of this widget.
- void timer_action (
- ) { parent.trigger_user_event(this,scrollable_region::next_free_user_event_number()); }
- /*!
- ensures
- - flips the state of cursor_visible
- !*/
-
- void move_cursor (
- unsigned long pos
- );
- /*!
- requires
- - pos <= text_.size()
- ensures
- - moves the cursor to the position given by pos and moves the text
- in the text box if necessary
- - if the position changes then the parent window will be updated
- !*/
-
- rectangle get_text_rect (
- ) const;
- /*!
- ensures
- - returns the rectangle that should contain the text in this widget
- !*/
-
- void adjust_total_rect (
- );
- /*!
- ensures
- - adjusts total_rect() so that it is big enough to contain the text
- currently in this object.
- !*/
-
- dlib::ustring text_;
- rgb_pixel text_color_;
- rgb_pixel bg_color_;
-
-
-
- bool recent_movement;
- bool has_focus;
- bool cursor_visible;
- long cursor_pos;
- rectangle cursor_rect;
-
- // this tells you what part of the text is highlighted
- long highlight_start;
- long highlight_end;
- long shift_pos;
- any_function<void()> text_modified_handler;
- any_function<void()> enter_key_handler;
- any_function<void()> focus_lost_handler;
-
- std::unique_ptr<text_box_style> style;
-
- timer<text_box> t;
-
- popup_menu_region right_click_menu;
-
- // restricted functions
- text_box(text_box&); // copy constructor
- text_box& operator=(text_box&); // assignment operator
-
-
- protected:
-
- void draw (
- const canvas& c
- ) const;
-
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- void on_string_put (
- const std::wstring &str
- );
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class check_box
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class check_box : public toggle_button
- {
- public:
- check_box(
- drawable_window& w
- ) : toggle_button(w)
- {
- set_style(toggle_button_style_check_box());
- }
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class radio_button
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class radio_button : public toggle_button
- {
- public:
- radio_button (
- drawable_window& w
- ) : toggle_button(w)
- {
- set_style(toggle_button_style_radio_button());
- }
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class tabbed_display
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class tabbed_display : public drawable
- {
- /*!
- INITIAL VALUE
- - tabs.size() == 0
- - selected_tab_ == 0
-
- CONVENTION
- - number_of_tabs() == tabs.size()
- - tab_name(idx) == tabs[idx]
- - if (tabs.size() > 0) then
- - selected_tab_ == the index of the tab that is currently selected
-
- - for all valid i:
- - tabs[i].width == mfont->compute_size(tabs[i].name)
- - tabs[i].rect == the rectangle that defines where this tab is
- - if (tabs[i].group != 0) then
- - tabs[i].group == a pointer to the widget_group for this tab.
-
- - left_pad == the amount of padding in a tab to the left of the name string.
- - right_pad == the amount of padding in a tab to the right of the name string.
- - top_pad == the amount of padding in a tab to the top of the name string.
- - bottom_pad == the amount of padding in a tab to the bottom of the name string.
-
- - if (event_handler.is_set()) then
- - event_handler() is what is called to process click events
- on this object.
- !*/
-
- public:
-
- tabbed_display(
- drawable_window& w
- );
-
- virtual ~tabbed_display(
- );
-
- void set_size (
- unsigned long width,
- unsigned long height
- );
-
- void set_number_of_tabs (
- unsigned long num
- );
-
- unsigned long selected_tab (
- ) const;
-
- unsigned long number_of_tabs (
- ) const;
-
- const std::string tab_name (
- unsigned long idx
- ) const;
-
- const std::wstring tab_wname (
- unsigned long idx
- ) const;
-
- const dlib::ustring& tab_uname (
- unsigned long idx
- ) const;
-
- void set_tab_name (
- unsigned long idx,
- const std::string& new_name
- );
-
- void set_tab_name (
- unsigned long idx,
- const std::wstring& new_name
- );
-
- void set_tab_name (
- unsigned long idx,
- const dlib::ustring& new_name
- );
-
- void set_pos (
- long x,
- long y
- );
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*eh)(unsigned long new_idx,unsigned long old_idx)
- )
- {
- auto_mutex M(m);
- event_handler = make_mfp(object,eh);
- }
-
- void set_click_handler (
- const any_function<void(unsigned long,unsigned long)>& eh
- )
- {
- auto_mutex M(m);
- event_handler = eh;
- }
-
- void set_tab_group (
- unsigned long idx,
- widget_group& group
- );
-
- void show (
- );
-
- void hide (
- );
-
- void enable (
- );
-
- void disable (
- );
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- void fit_to_contents (
- );
-
- protected:
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void draw (
- const canvas& c
- ) const;
-
- private:
- void recompute_tabs (
- );
- /*!
- ensures
- - recomputes the rectangles for all the tabs and makes this object
- wider if needed
- !*/
-
- void draw_tab (
- const rectangle& tab,
- const canvas& c
- ) const;
- /*!
- ensures
- - draws the outline of a tab as given by the rectangle onto c
- !*/
-
- struct tab_data
- {
- tab_data() : width(0), group(0) {}
-
- dlib::ustring name;
- unsigned long width;
- rectangle rect;
- widget_group* group;
- };
-
- unsigned long selected_tab_;
-
- array<tab_data> tabs;
-
- const long left_pad;
- const long right_pad;
- const long top_pad;
- const long bottom_pad;
-
- any_function<void(unsigned long,unsigned long)> event_handler;
-
- // restricted functions
- tabbed_display(tabbed_display&); // copy constructor
- tabbed_display& operator=(tabbed_display&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class named_rectangle
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class named_rectangle : public drawable
- {
- /*!
- INITIAL VALUE
- name == ""
-
- CONVENTION
- name_ == name()
- !*/
-
- public:
-
- named_rectangle(
- drawable_window& w
- );
-
- virtual ~named_rectangle(
- );
-
- void set_size (
- unsigned long width,
- unsigned long height
- );
-
- void set_name (
- const std::string& name
- );
-
- void set_name (
- const std::wstring& name
- );
-
- void set_name (
- const dlib::ustring& name
- );
-
- const std::string name (
- ) const;
-
- const std::wstring wname (
- ) const;
-
- const dlib::ustring uname (
- ) const;
-
- void wrap_around (
- const rectangle& rect
- );
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- protected:
-
- void draw (
- const canvas& c
- ) const;
-
- private:
-
- void make_name_fit_in_rect (
- );
-
- dlib::ustring name_;
- unsigned long name_width;
- unsigned long name_height;
-
- // restricted functions
- named_rectangle(named_rectangle&); // copy constructor
- named_rectangle& operator=(named_rectangle&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class mouse_tracker
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class mouse_tracker : public draggable
- {
-
- public:
-
- mouse_tracker(
- drawable_window& w
- );
-
- ~mouse_tracker(
- );
-
- void show (
- );
-
- void hide (
- );
-
- void enable (
- );
-
- void disable (
- );
-
- void set_pos (
- long x,
- long y
- );
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- protected:
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_drag (
- );
-
- void draw (
- const canvas& c
- ) const;
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
-
- private:
-
- const long offset;
- named_rectangle nr;
- label x_label;
- label y_label;
- std::ostringstream sout;
-
- long click_x, click_y;
-
- // restricted functions
- mouse_tracker(mouse_tracker&); // copy constructor
- mouse_tracker& operator=(mouse_tracker&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // function message_box()
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace message_box_helper
- {
- class box_win : public drawable_window
- {
- void initialize (
- );
- public:
- box_win (
- const std::string& title_,
- const std::string& message_
- );
-
- box_win (
- const std::wstring& title_,
- const std::wstring& message_
- );
-
- box_win (
- const dlib::ustring& title_,
- const dlib::ustring& message_
- );
-
- ~box_win (
- );
-
- void set_click_handler (
- const any_function<void()>& event_handler_
- )
- {
- auto_mutex M(wm);
- event_handler = event_handler_;
- }
-
- private:
-
- static void deleter_thread (
- void* param
- );
-
- void on_click (
- );
-
- on_close_return_code on_window_close (
- );
-
- const std::wstring title;
- const std::wstring message;
- label msg;
- button btn_ok;
-
- any_function<void()> event_handler;
- };
-
- class blocking_box_win : public drawable_window
- {
- void initialize (
- );
-
- public:
- blocking_box_win (
- const std::string& title_,
- const std::string& message_
- );
-
- blocking_box_win (
- const std::wstring& title_,
- const std::wstring& message_
- );
-
- blocking_box_win (
- const dlib::ustring& title_,
- const dlib::ustring& message_
- );
-
- ~blocking_box_win (
- );
-
- private:
-
- void on_click (
- );
-
- const std::wstring title;
- const std::wstring message;
- label msg;
- button btn_ok;
- };
- }
-
- template <
- typename T
- >
- void message_box (
- const std::string& title,
- const std::string& message,
- T& object,
- void (T::*event_handler)()
- )
- {
- using namespace message_box_helper;
- box_win* win = new box_win(title,message);
- win->set_click_handler(make_mfp(object,event_handler));
- }
-
- inline void message_box (
- const std::string& title,
- const std::string& message,
- const any_function<void()>& event_handler
- )
- {
- using namespace message_box_helper;
- box_win* win = new box_win(title,message);
- win->set_click_handler(event_handler);
- }
-
- inline void message_box (
- const std::string& title,
- const std::string& message
- )
- {
- using namespace message_box_helper;
- new box_win(title,message);
- }
-
- inline void message_box_blocking (
- const std::string& title,
- const std::string& message
- )
- {
- using namespace message_box_helper;
- blocking_box_win w(title,message);
- w.wait_until_closed();
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class list_box
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace list_box_helper{
- template <typename S = std::string>
- class list_box : public scrollable_region,
- public enumerable<const S>
- {
- /*!
- INITIAL VALUE
- - ms_enabled == false
- - items.size() == 0
- - last_selected = 0
-
- CONVENTION
- - size() == items.size()
- - (*this)[i] == items[i].name
- - is_selected(i) == items[i].is_selected
- - ms_enabled == multiple_select_enabled()
-
- - items[i].width == the width of items[i].name as given by font::compute_size()
- - items[i].height == the height of items[i].name as given by font::compute_size()
-
- - last_selected == the last item the user selected
- !*/
-
- public:
-
- list_box(
- drawable_window& w
- );
-
- ~list_box(
- );
-
- bool is_selected (
- unsigned long index
- ) const;
-
- void select (
- unsigned long index
- );
-
- void unselect (
- unsigned long index
- );
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style_
- )
- {
- auto_mutex M(m);
- style.reset(new style_type(style_));
- scrollable_region::set_style(style_.get_scrollable_region_style());
- parent.invalidate_rectangle(rect);
- }
-
- template <typename T>
- void get_selected (
- T& list
- ) const
- {
- auto_mutex M(m);
- list.clear();
- for (unsigned long i = 0; i < items.size(); ++i)
- {
- if (items[i].is_selected)
- {
- unsigned long idx = i;
- list.enqueue(idx);
- }
- }
- }
-
- template <typename T>
- void load (
- const T& list
- )
- {
- auto_mutex M(m);
- items.clear();
- unsigned long i = 0;
- items.set_max_size(list.size());
- items.set_size(list.size());
- list.reset();
- unsigned long max_width = 0;
- unsigned long total_height = 0;
- while (list.move_next())
- {
- items[i].is_selected = false;
- items[i].name = list.element();
- mfont->compute_size(items[i].name,items[i].width, items[i].height);
-
- if (items[i].width > max_width)
- max_width = items[i].width;
- total_height += items[i].height;
-
- ++i;
- }
- set_total_rect_size(max_width, total_height);
-
- parent.invalidate_rectangle(rect);
- last_selected = 0;
- }
-
- const S& operator[] (
- unsigned long index
- ) const;
-
- bool multiple_select_enabled (
- ) const;
-
- void enable_multiple_select (
- );
-
- void disable_multiple_select (
- );
-
- template <
- typename T
- >
- void set_double_click_handler (
- T& object,
- void (T::*eh)(unsigned long index)
- ) { auto_mutex M(m); event_handler = make_mfp(object,eh); }
-
- void set_double_click_handler (
- const any_function<void(unsigned long)>& eh
- ) { auto_mutex M(m); event_handler = eh; }
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*eh)(unsigned long index)
- ) { auto_mutex M(m); single_click_event_handler = make_mfp(object,eh); }
-
- void set_click_handler (
- const any_function<void(unsigned long)>& eh
- ) { auto_mutex M(m); single_click_event_handler = eh; }
-
- bool at_start (
- ) const;
-
- void reset (
- ) const;
-
- bool current_element_valid (
- ) const;
-
- const S& element (
- ) const;
-
- const S& element (
- );
-
- bool move_next (
- ) const;
-
- size_t size (
- ) const;
-
- unsigned long get_selected (
- ) const;
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- private:
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void draw (
- const canvas& c
- ) const;
-
- template <typename SS>
- struct data
- {
- SS name;
- bool is_selected;
- unsigned long width;
- unsigned long height;
- };
-
- bool ms_enabled;
- array<data<S> > items;
- any_function<void(unsigned long)> event_handler;
- any_function<void(unsigned long)> single_click_event_handler;
- unsigned long last_selected;
-
- std::unique_ptr<list_box_style> style;
-
- // restricted functions
- list_box(list_box&); // copy constructor
- list_box& operator=(list_box&); // assignment operator
- };
- }
- typedef list_box_helper::list_box<std::string> list_box;
- typedef list_box_helper::list_box<std::wstring> wlist_box;
- typedef list_box_helper::list_box<dlib::ustring> ulist_box;
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // function open_file_box()
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace open_file_box_helper
- {
- class box_win : public drawable_window
- {
- public:
- box_win (
- const std::string& title,
- bool has_text_field = false
- );
-
- ~box_win (
- );
-
- void set_click_handler (
- const any_function<void(const std::string&)>& event_handler_
- )
- {
- auto_mutex M(wm);
- event_handler = event_handler_;
- }
-
- private:
-
- void set_sizes(
- );
-
- void on_window_resized (
- );
-
- void deleter_thread (
- );
-
- void enter_folder (
- const std::string& folder_name
- );
-
- void on_dirs_click (
- unsigned long idx
- );
-
- void on_files_click (
- unsigned long idx
- );
-
- void on_files_double_click (
- unsigned long
- );
-
- void on_cancel_click (
- );
-
- void on_open_click (
- );
-
- void on_path_button_click (
- toggle_button& btn
- );
-
- bool set_dir (
- const std::string& dir
- );
-
- void on_root_click (
- );
-
- on_close_return_code on_window_close (
- );
-
- label lbl_dirs;
- label lbl_files;
- label lbl_file_name;
- list_box lb_dirs;
- list_box lb_files;
- button btn_ok;
- button btn_cancel;
- toggle_button btn_root;
- text_field tf_file_name;
- std::string path;
- std::string prefix;
- int cur_dir;
-
- any_function<void(const std::string&)> event_handler;
- sequence<std::unique_ptr<toggle_button> >::kernel_2a_c sob;
- };
- }
-
- template <
- typename T
- >
- void open_file_box (
- T& object,
- void (T::*event_handler)(const std::string&)
- )
- {
- using namespace open_file_box_helper;
- box_win* win = new box_win("Open File",true);
- win->set_click_handler(make_mfp(object,event_handler));
- }
-
- inline void open_file_box (
- const any_function<void(const std::string&)>& event_handler
- )
- {
- using namespace open_file_box_helper;
- box_win* win = new box_win("Open File",true);
- win->set_click_handler(event_handler);
- }
-
- template <
- typename T
- >
- void open_existing_file_box (
- T& object,
- void (T::*event_handler)(const std::string&)
- )
- {
- using namespace open_file_box_helper;
- box_win* win = new box_win("Open File");
- win->set_click_handler(make_mfp(object,event_handler));
- }
-
- inline void open_existing_file_box (
- const any_function<void(const std::string&)>& event_handler
- )
- {
- using namespace open_file_box_helper;
- box_win* win = new box_win("Open File");
- win->set_click_handler(event_handler);
- }
-
- template <
- typename T
- >
- void save_file_box (
- T& object,
- void (T::*event_handler)(const std::string&)
- )
- {
- using namespace open_file_box_helper;
- box_win* win = new box_win("Save File",true);
- win->set_click_handler(make_mfp(object,event_handler));
- }
-
- inline void save_file_box (
- const any_function<void(const std::string&)>& event_handler
- )
- {
- using namespace open_file_box_helper;
- box_win* win = new box_win("Save File",true);
- win->set_click_handler(event_handler);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class menu_bar
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class menu_bar : public drawable
- {
- /*!
- INITIAL VALUE
- - menus.size() == 0
- - open_menu == 0
-
- CONVENTION
- - size() == menus.size()
- - all menu data is stored in menus
- - menus[x].name == the name of the xth menu
- - if (menus[x].underline_pos != std::string::npos) then
- - menus[x].underline_pos == the position of the character in the
- menu name that should be underlined
- - menus[x].underline_p1 != menus[x].underline_p2
- and these two points define the underline bar
- - else
- - menus[x].underline_p1 == menus[x].underline_p2
- - menus[x].menu == menu(x)
- - menus[x].rect == the rectangle in which menus[x].name is drawn
- - menus[x].bgrect == the rectangle for the xth menu button
-
- - if (there is an open menu on the screen) then
- - open_menu == the index of the open menu from menus
- - else
- - open_menu == menus.size()
- !*/
-
- public:
- menu_bar(
- drawable_window& w
- );
-
- ~menu_bar();
-
- // this function does nothing
- void set_pos(long,long){}
-
- void set_main_font (
- const std::shared_ptr<font>& f
- );
-
- void set_number_of_menus (
- unsigned long num
- );
-
- unsigned long number_of_menus (
- ) const;
-
- void set_menu_name (
- unsigned long idx,
- const std::string name,
- char underline_ch = '\0'
- );
-
- void set_menu_name (
- unsigned long idx,
- const std::wstring name,
- char underline_ch = '\0'
- );
-
- void set_menu_name (
- unsigned long idx,
- const dlib::ustring name,
- char underline_ch = '\0'
- );
-
- const std::string menu_name (
- unsigned long idx
- ) const;
-
- const std::wstring menu_wname (
- unsigned long idx
- ) const;
-
- const dlib::ustring menu_uname (
- unsigned long idx
- ) const;
-
- popup_menu& menu (
- unsigned long idx
- );
-
- const popup_menu& menu (
- unsigned long idx
- ) const;
-
- protected:
-
- void on_window_resized (
- );
-
- void draw (
- const canvas& c
- ) const;
-
- void on_window_moved (
- );
-
- void on_focus_lost (
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long ,
- long x,
- long y,
- bool
- );
-
- void on_mouse_move (
- unsigned long ,
- long x,
- long y
- );
-
- void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- private:
-
- void show_menu (
- unsigned long i
- );
-
- void hide_menu (
- );
-
- void on_popup_hide (
- );
-
- void compute_menu_geometry (
- );
-
- void adjust_position (
- );
-
- struct menu_data
- {
- menu_data():underline_pos(dlib::ustring::npos){}
-
- dlib::ustring name;
- dlib::ustring::size_type underline_pos;
- popup_menu menu;
- rectangle rect;
- rectangle bgrect;
- point underline_p1;
- point underline_p2;
- };
-
- array<menu_data> menus;
- unsigned long open_menu;
-
- // restricted functions
- menu_bar(menu_bar&); // copy constructor
- menu_bar& operator=(menu_bar&); // assignment operator
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class directed_graph_drawer
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename graph_type>
- class directed_graph_drawer : public zoomable_region
- {
- /*!
- INITIAL VALUE
- - edge_selected == false
- - mouse_drag == false
- - selected_node == 0
- - graph_.number_of_nodes() == 0
- - external_graph.number_of_nodes() == 0
- - radius == 25
- - last_mouse_click_in_display == false
-
- CONVENTION
- - radius == the radius of the nodes when they aren't zoomed
- - external_graph and graph_ have the same graph structure
- - external_graph == graph()
- - external_graph.node(i) == graph_node(i)
-
- - if (one of the nodes is selected) then
- - selected_node < graph_.number_of_nodes()
- - graph_.node(selected_node) == the selected node
- - else
- - selected_node == graph_.number_of_nodes()
-
- - if (the user is dragging a node with the mouse) then
- - mouse_drag == true
- - drag_offset == the vector from the mouse position to the
- center of the node
- - else
- - mouse_drag == false
-
- - if (the user has selected an edge) then
- - edge_selected == true
- - the parent node is graph_.node(selected_edge_parent)
- - the child node is graph_.node(selected_edge_parent)
- - else
- - edge_selected == false
-
- - for all valid i:
- - graph_.node(i).data.p == the center of the node in graph space
- - graph_.node(i).data.name == node_label(i)
- - graph_.node(i).data.color == node_color(i)
- - graph_.node(i).data.str_rect == a rectangle sized to contain graph_.node(i).data.name
-
- - if (the last mouse click in our parent window as in our display_rect_ ) then
- - last_mouse_click_in_display == true
- - else
- - last_mouse_click_in_display == false
- !*/
-
- public:
- directed_graph_drawer (
- drawable_window& w
- ) :
- zoomable_region(w,MOUSE_CLICK | MOUSE_WHEEL | KEYBOARD_EVENTS),
- radius(25),
- edge_selected(false),
- last_mouse_click_in_display(false)
- {
- mouse_drag = false;
- selected_node = 0;
-
- // Whenever you make your own drawable (or inherit from draggable or button_action)
- // you have to remember to call this function to enable the events. The idea
- // here is that you can perform whatever setup you need to do to get your
- // object into a valid state without needing to worry about event handlers
- // triggering before you are ready.
- enable_events();
- }
-
- ~directed_graph_drawer (
- )
- {
- // Disable all further events for this drawable object. We have to do this
- // because we don't want draw() events coming to this object while or after
- // it has been destructed.
- disable_events();
-
- // Tell the parent window to redraw its area that previously contained this
- // drawable object.
- parent.invalidate_rectangle(rect);
- }
-
- void clear_graph (
- )
- {
- auto_mutex M(m);
- graph_.clear();
- external_graph.clear();
- parent.invalidate_rectangle(display_rect());
- }
-
- const typename graph_type::node_type& graph_node (
- unsigned long i
- ) const
- {
- DLIB_ASSERT ( i < number_of_nodes() ,
- "\tgraph_type::node_type& directed_graph_drawer::graph_node(i)"
- << "\n\ti: " << i
- << "\n\tnumber_of_nodes(): " << number_of_nodes()
- );
- return external_graph.node(i);
- }
-
- typename graph_type::node_type& graph_node (
- unsigned long i
- )
- {
- DLIB_ASSERT ( i < number_of_nodes() ,
- "\tgraph_type::node_type& directed_graph_drawer::graph_node(i)"
- << "\n\ti: " << i
- << "\n\tnumber_of_nodes(): " << number_of_nodes()
- );
- return external_graph.node(i);
- }
-
- const graph_type& graph (
- ) const
- {
- return external_graph;
- }
-
- void save_graph (
- std::ostream& out
- )
- {
- auto_mutex M(m);
- serialize(external_graph, out);
- serialize(graph_, out);
- parent.invalidate_rectangle(display_rect());
- }
-
- void load_graph (
- std::istream& in
- )
- {
- auto_mutex M(m);
- deserialize(external_graph, in);
- deserialize(graph_, in);
- parent.invalidate_rectangle(display_rect());
- }
-
- unsigned long number_of_nodes (
- ) const
- {
- auto_mutex M(m);
- return graph_.number_of_nodes();
- }
-
- void set_node_label (
- unsigned long i,
- const std::string& label
- )
- {
- set_node_label(i, convert_mbstring_to_wstring(label));
- }
-
- void set_node_label (
- unsigned long i,
- const std::wstring& label
- )
- {
- set_node_label(i, convert_wstring_to_utf32(label));
- }
-
- void set_node_label (
- unsigned long i,
- const dlib::ustring& label
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( i < number_of_nodes() ,
- "\tvoid directed_graph_drawer::set_node_label(i,label)"
- << "\n\ti: " << i
- << "\n\tlabel: " << narrow(label)
- << "\n\tnumber_of_nodes(): " << number_of_nodes()
- );
- graph_.node(i).data.name = label.c_str();
- unsigned long width, height;
- mfont->compute_size(label,width,height);
- graph_.node(i).data.str_rect = rectangle(width,height);
- parent.invalidate_rectangle(display_rect());
- }
-
- void set_node_color (
- unsigned long i,
- rgb_pixel color
- )
- {
- auto_mutex M(m);
- DLIB_ASSERT ( i < number_of_nodes() ,
- "\tvoid directed_graph_drawer::set_node_color(i,label)"
- << "\n\ti: " << i
- << "\n\tnumber_of_nodes(): " << number_of_nodes()
- );
- graph_.node(i).data.color = color;
- parent.invalidate_rectangle(display_rect());
- }
-
- rgb_pixel node_color (
- unsigned long i
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( i < number_of_nodes() ,
- "\trgb_pixel directed_graph_drawer::node_color(i)"
- << "\n\ti: " << i
- << "\n\tnumber_of_nodes(): " << number_of_nodes()
- );
- return graph_.node(i).data.color;
- }
-
- const std::string node_label (
- unsigned long i
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( i < number_of_nodes() ,
- "\tconst std::ustring directed_graph_drawer::node_label(i)"
- << "\n\ti: " << i
- << "\n\tnumber_of_nodes(): " << number_of_nodes()
- );
- return narrow(graph_.node(i).data.name);
- }
-
- const std::wstring node_wlabel (
- unsigned long i
- ) const
- {
- return convert_utf32_to_wstring(node_ulabel(i));
- }
-
- const dlib::ustring node_ulabel (
- unsigned long i
- ) const
- {
- auto_mutex M(m);
- DLIB_ASSERT ( i < number_of_nodes() ,
- "\tconst std::ustring directed_graph_drawer::node_label(i)"
- << "\n\ti: " << i
- << "\n\tnumber_of_nodes(): " << number_of_nodes()
- );
- return graph_.node(i).data.name.c_str();
- }
-
- template <
- typename T
- >
- void set_node_selected_handler (
- T& object,
- void (T::*event_handler_)(unsigned long)
- )
- {
- auto_mutex M(m);
- node_selected_handler = make_mfp(object,event_handler_);
- }
-
- void set_node_selected_handler (
- const any_function<void(unsigned long)>& event_handler_
- )
- {
- auto_mutex M(m);
- node_selected_handler = event_handler_;
- }
-
- template <
- typename T
- >
- void set_node_deselected_handler (
- T& object,
- void (T::*event_handler_)(unsigned long)
- )
- {
- auto_mutex M(m);
- node_deselected_handler = make_mfp(object,event_handler_);
- }
-
- void set_node_deselected_handler (
- const any_function<void(unsigned long)>& event_handler_
- )
- {
- auto_mutex M(m);
- node_deselected_handler = event_handler_;
- }
-
- template <
- typename T
- >
- void set_node_deleted_handler (
- T& object,
- void (T::*event_handler_)()
- )
- {
- auto_mutex M(m);
- node_deleted_handler = make_mfp(object,event_handler_);
- }
-
- void set_node_deleted_handler (
- const any_function<void()>& event_handler_
- )
- {
- auto_mutex M(m);
- node_deleted_handler = event_handler_;
- }
-
- template <
- typename T
- >
- void set_graph_modified_handler (
- T& object,
- void (T::*event_handler_)()
- )
- {
- auto_mutex M(m);
- graph_modified_handler = make_mfp(object,event_handler_);
- }
-
- void set_graph_modified_handler (
- const any_function<void()>& event_handler_
- )
- {
- auto_mutex M(m);
- graph_modified_handler = event_handler_;
- }
-
- protected:
-
- void on_keydown (
- unsigned long key,
- bool ,
- unsigned long
- )
- {
- // ignore all keyboard input if the last thing the user clicked on
- // wasn't the display area
- if (last_mouse_click_in_display == false)
- return;
-
- // if a node is selected
- if (selected_node != graph_.number_of_nodes())
- {
- // deselect the node if the user hits escape
- if (key == base_window::KEY_ESC)
- {
- parent.invalidate_rectangle(display_rect());
- if (node_deselected_handler.is_set())
- node_deselected_handler(selected_node);
- selected_node = graph_.number_of_nodes();
- }
-
- // delete the node if the user hits delete
- if (key == base_window::KEY_DELETE || key == base_window::KEY_BACKSPACE)
- {
- parent.invalidate_rectangle(display_rect());
- graph_.remove_node(selected_node);
- external_graph.remove_node(selected_node);
- selected_node = graph_.number_of_nodes();
- mouse_drag = false;
- if (graph_modified_handler.is_set())
- graph_modified_handler();
- if (node_deleted_handler.is_set())
- node_deleted_handler();
- }
- }
-
- // if an edge is selected
- if (edge_selected)
- {
- // deselect the node if the user hits escape
- if (key == base_window::KEY_ESC)
- {
- parent.invalidate_rectangle(display_rect());
- edge_selected = false;
- }
-
- // delete the node if the user hits delete
- if (key == base_window::KEY_DELETE || key == base_window::KEY_BACKSPACE)
- {
- parent.invalidate_rectangle(display_rect());
- graph_.remove_edge(selected_edge_parent, selected_edge_child);
- external_graph.remove_edge(selected_edge_parent, selected_edge_child);
- edge_selected = false;
-
- if (graph_modified_handler.is_set())
- graph_modified_handler();
- }
- }
- }
-
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- )
- {
- if (mouse_drag)
- {
- const point p(nearest_point(display_rect(),point(x,y)));
-
- point center = drag_offset + p;
- graph_.node(selected_node).data.p = gui_to_graph_space(center);
- parent.invalidate_rectangle(display_rect());
- }
- else
- {
- zoomable_region::on_mouse_move(state,x,y);
- }
-
- // check if the mouse isn't being dragged anymore
- if ((state & base_window::LEFT) == 0)
- {
- mouse_drag = false;
- }
- }
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- )
- {
- mouse_drag = false;
- zoomable_region::on_mouse_up(btn,state,x,y);
- }
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- )
- {
- bool redraw = false;
-
- if (display_rect().contains(x,y) &&
- (btn == base_window::RIGHT || btn == base_window::LEFT) &&
- (state & base_window::SHIFT) == 0 )
- {
- // start out saying no edge is selected
- if (edge_selected)
- {
- edge_selected = false;
- redraw = true;
- }
-
- bool click_hit_node = false;
- dlib::vector<double,2> p(gui_to_graph_space(point(x,y)));
- // check if this click is on an existing node
- for (unsigned long i = 0; i < graph_.number_of_nodes(); ++i)
- {
- dlib::vector<double,2> n(graph_.node(i).data.p);
- if ((p-n).length() < radius)
- {
- click_hit_node = true;
- point center = graph_to_gui_space(graph_.node(i).data.p);
- mouse_drag = true;
- drag_offset = center - point(x,y);
-
- // only do something if the click isn't on the currently
- // selected node
- if (selected_node != i)
- {
- // send out the deselected event if appropriate
- if (selected_node != graph_.number_of_nodes() && node_deselected_handler.is_set())
- node_deselected_handler(selected_node);
-
- selected_node = i;
- redraw = true;
- if (node_selected_handler.is_set())
- node_selected_handler(selected_node);
- }
- break;
- }
- }
-
- // if the click didn't hit any node then make sure nothing is selected
- if (click_hit_node == false && selected_node != graph_.number_of_nodes())
- {
- if (node_deselected_handler.is_set())
- node_deselected_handler(selected_node);
- selected_node = graph_.number_of_nodes();
- redraw = true;
- }
-
-
- // check if this click is on an edge if we didn't click on a node
- if (click_hit_node == false)
- {
- for (unsigned long n = 0; n < graph_.number_of_nodes() && edge_selected == false; ++n)
- {
- const dlib::vector<double,2> parent_center(graph_to_gui_space(graph_.node(n).data.p));
- for (unsigned long e = 0; e < graph_.node(n).number_of_children() && edge_selected == false; ++e)
- {
- const dlib::vector<double,2> child_center(graph_to_gui_space(graph_.node(n).child(e).data.p));
-
- rectangle area;
- area += parent_center;
- area += child_center;
- // if the point(x,y) is between the two nodes then lets consider it further
- if (area.contains(point(x,y)))
- {
- p = point(x,y);
- const dlib::vector<double> z(0,0,1);
- // find the distance from the line between the two nodes
- const dlib::vector<double,2> perpendicular(z.cross(parent_center-child_center).normalize());
- double distance = std::abs((child_center-p).dot(perpendicular));
- if (distance < 8)
- {
- edge_selected = true;
- selected_edge_parent = n;
- selected_edge_child = graph_.node(n).child(e).index();
- redraw = true;
- }
- }
- }
- }
- }
-
-
- // if the click didn't land on any node then add a new one if this was
- // a right mouse button click
- if (click_hit_node == false && btn == base_window::RIGHT)
- {
- const unsigned long n = graph_.add_node();
- external_graph.add_node();
-
- graph_.node(n).data.p = gui_to_graph_space(point(x,y));
-
- redraw = true;
- selected_node = n;
- mouse_drag = false;
- if (graph_modified_handler.is_set())
- graph_modified_handler();
-
- if (node_selected_handler.is_set())
- node_selected_handler(selected_node);
-
- }
- else if (selected_node == graph_.number_of_nodes())
- {
- // in this case the click landed in the white area between nodes
- zoomable_region::on_mouse_down( btn, state, x, y, is_double_click);
- }
- }
-
- // If the user is shift clicking with the mouse then see if we
- // should add a new edge.
- if (display_rect().contains(x,y) &&
- btn == base_window::LEFT &&
- (state & base_window::SHIFT) &&
- selected_node != graph_.number_of_nodes() )
- {
- dlib::vector<double,2> p(gui_to_graph_space(point(x,y)));
- // check if this click is on an existing node
- for (unsigned long i = 0; i < graph_.number_of_nodes(); ++i)
- {
- dlib::vector<double,2> n(graph_.node(i).data.p);
- if ((p-n).length() < radius)
- {
- // add the edge if it doesn't already exist and isn't an edge back to
- // the same node
- if (graph_.has_edge(selected_node,i) == false && selected_node != i &&
- graph_.has_edge(i, selected_node) == false)
- {
- graph_.add_edge(selected_node,i);
- external_graph.add_edge(selected_node,i);
- redraw = true;
-
- if (graph_modified_handler.is_set())
- graph_modified_handler();
- }
- break;
- }
- }
- }
-
-
- if (redraw)
- parent.invalidate_rectangle(display_rect());
-
-
- if (display_rect().contains(x,y) == false)
- last_mouse_click_in_display = false;
- else
- last_mouse_click_in_display = true;
- }
-
- void draw (
- const canvas& c
- ) const
- {
- zoomable_region::draw(c);
-
- rectangle area = c.intersect(display_rect());
- if (area.is_empty() == true)
- return;
-
-
- if (enabled)
- fill_rect(c,display_rect(),255);
- else
- fill_rect(c,display_rect(),128);
-
-
- const unsigned long rad = static_cast<unsigned long>(radius*zoom_scale());
- point center;
-
-
- // first draw all the edges
- for (unsigned long i = 0; i < graph_.number_of_nodes(); ++i)
- {
- center = graph_to_gui_space(graph_.node(i).data.p);
- const rectangle circle_area(centered_rect(center,2*(rad+8),2*(rad+8)));
-
- // draw lines to all this node's parents
- const dlib::vector<double> z(0,0,1);
- for (unsigned long j = 0; j < graph_.node(i).number_of_parents(); ++j)
- {
- point p(graph_to_gui_space(graph_.node(i).parent(j).data.p));
-
- rgb_pixel color(0,0,0);
- // if this is the selected edge then draw it with red instead of black
- if (edge_selected && selected_edge_child == i && selected_edge_parent == graph_.node(i).parent(j).index())
- {
- color.red = 255;
- // we need to be careful when drawing this line to not draw it over the node dots since it
- // has a different color from them and would look weird
- dlib::vector<double,2> v(p-center);
- v = v.normalize()*rad;
- draw_line(c,center+v,p-v ,color, area);
- }
- else
- {
- draw_line(c,center,p ,color, area);
- }
-
-
- // draw the triangle pointing to this node
- if (area.intersect(circle_area).is_empty() == false)
- {
- dlib::vector<double,2> v(p-center);
- v = v.normalize();
-
- dlib::vector<double,2> cross = z.cross(v).normalize();
- dlib::vector<double,2> r(center + v*rad);
- for (double i = 0; i < 8*zoom_scale(); i += 0.1)
- draw_line(c,(r+v*i)+cross*i, (r+v*i)-cross*i,color,area);
- }
- }
- }
-
-
- // now draw all the node dots
- for (unsigned long i = 0; i < graph_.number_of_nodes(); ++i)
- {
- center = graph_to_gui_space(graph_.node(i).data.p);
- const rectangle circle_area(centered_rect(center,2*(rad+8),2*(rad+8)));
-
- // draw the actual dot for this node
- if (area.intersect(circle_area).is_empty()==false)
- {
- rgb_alpha_pixel color;
- assign_pixel(color, graph_.node(i).data.color);
- // this node is in area so lets draw it and all of it's edges as well
- draw_solid_circle(c,center,rad-3,color,area);
- color.alpha = 240;
- draw_circle(c,center,rad-3,color,area);
- color.alpha = 200;
- draw_circle(c,center,rad-2.5,color,area);
- color.alpha = 160;
- draw_circle(c,center,rad-2.0,color,area);
- color.alpha = 120;
- draw_circle(c,center,rad-1.5,color,area);
- color.alpha = 80;
- draw_circle(c,center,rad-1.0,color,area);
- color.alpha = 40;
- draw_circle(c,center,rad-0.5,color,area);
-
- }
-
-
- if (i == selected_node)
- draw_circle(c,center,rad+5,rgb_pixel(0,0,255),area);
- }
-
-
- // now draw all the strings last
- for (unsigned long i = 0; i < graph_.number_of_nodes(); ++i)
- {
- center = graph_to_gui_space(graph_.node(i).data.p);
- rectangle circle_area(centered_rect(center,2*rad+3,2*rad+3));
- if (area.intersect(circle_area).is_empty()==false)
- {
- rgb_pixel color = graph_.node(i).data.color;
- // invert this color
- color.red = 255-color.red;
- color.green = 255-color.green;
- color.blue = 255-color.blue;
- sout << i;
- unsigned long width, height;
- mfont->compute_size(sout.str(),width,height);
- rectangle str_rect(centered_rect(center, width,height));
- if (circle_area.contains(str_rect))
- {
- mfont->draw_string(c,str_rect,sout.str(),color,0,std::string::npos,area);
-
- // draw the label for this node if it isn't empty
- if(graph_.node(i).data.name.size() > 0)
- {
- rectangle str_rect(graph_.node(i).data.str_rect);
- str_rect = centered_rect(center.x(), center.y()-rad-mfont->height(), str_rect.width(), str_rect.height());
- mfont->draw_string(c,str_rect,graph_.node(i).data.name,0,0,std::string::npos,area);
- }
- }
- sout.str("");
- }
- }
- }
-
- private:
-
- struct data
- {
- data() : color(0,0,0) {}
- vector<double> p;
- dlib::ustring name;
- rectangle str_rect;
- rgb_pixel color;
- };
-
- friend void serialize(const data& item, std::ostream& out)
- {
- serialize(item.p, out);
- serialize(item.name, out);
- serialize(item.str_rect, out);
- serialize(item.color, out);
- }
-
- friend void deserialize(data& item, std::istream& in)
- {
- deserialize(item.p, in);
- deserialize(item.name, in);
- deserialize(item.str_rect, in);
- deserialize(item.color, in);
- }
-
- mutable std::ostringstream sout;
-
- const double radius;
- unsigned long selected_node;
- bool mouse_drag; // true if the user is dragging a node
- point drag_offset;
-
- bool edge_selected;
- unsigned long selected_edge_parent;
- unsigned long selected_edge_child;
-
- any_function<void(unsigned long)> node_selected_handler;
- any_function<void(unsigned long)> node_deselected_handler;
- any_function<void()> node_deleted_handler;
- any_function<void()> graph_modified_handler;
-
- graph_type external_graph;
- // rebind the graph_ type to make us a graph_ of data structs
- typename graph_type::template rebind<data,char, typename graph_type::mem_manager_type>::other graph_;
-
- bool last_mouse_click_in_display;
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class text_grid
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_grid : public scrollable_region
- {
- /*!
- INITIAL VALUE
- - has_focus == false
- - vertical_scroll_increment() == 10
- - horizontal_scroll_increment() == 10
- - border_color_ == rgb_pixel(128,128,128)
-
- CONVENTION
- - grid.nr() == row_height.size()
- - grid.nc() == col_width.size()
- - border_color() == border_color_
- - text(r,c) == grid[r][c].text
- - text_color(r,c) == grid[r][c].text_color
- - background_color(r,c) == grid[r][c].bg_color
-
- - if (the user has clicked on this widget and caused one of the
- boxes to have input focus) then
- - has_focus == true
- - grid[active_row][active_col] == the active text box
- - cursor_pos == the position of the cursor in the above box
- - if (the cursor should be displayed) then
- - show_cursor == true
- - else
- - show_cursor == false
- - else
- - has_focus == false
- !*/
-
- public:
- text_grid (
- drawable_window& w
- );
-
- ~text_grid (
- );
-
- void set_grid_size (
- unsigned long rows,
- unsigned long cols
- );
-
- unsigned long number_of_columns (
- ) const;
-
- unsigned long number_of_rows (
- ) const;
-
- int next_free_user_event_number (
- ) const;
-
- rgb_pixel border_color (
- ) const;
-
- void set_border_color (
- rgb_pixel color
- );
-
- const std::string text (
- unsigned long row,
- unsigned long col
- ) const;
-
- const std::wstring wtext (
- unsigned long row,
- unsigned long col
- ) const;
-
- const dlib::ustring utext (
- unsigned long row,
- unsigned long col
- ) const;
-
- void set_text (
- unsigned long row,
- unsigned long col,
- const std::string& str
- );
-
- void set_text (
- unsigned long row,
- unsigned long col,
- const std::wstring& str
- );
-
- void set_text (
- unsigned long row,
- unsigned long col,
- const dlib::ustring& str
- );
-
- const rgb_pixel text_color (
- unsigned long row,
- unsigned long col
- ) const;
-
- void set_text_color (
- unsigned long row,
- unsigned long col,
- const rgb_pixel color
- );
-
- const rgb_pixel background_color (
- unsigned long row,
- unsigned long col
- ) const;
-
- void set_background_color (
- unsigned long row,
- unsigned long col,
- const rgb_pixel color
- );
-
- bool is_editable (
- unsigned long row,
- unsigned long col
- ) const;
-
- void set_editable (
- unsigned long row,
- unsigned long col,
- bool editable
- );
-
- void set_column_width (
- unsigned long col,
- unsigned long width
- );
-
- void set_row_height (
- unsigned long row,
- unsigned long height
- );
-
- void disable (
- );
-
- void hide (
- );
-
- template <
- typename T
- >
- void set_text_modified_handler (
- T& object,
- void (T::*eh)(unsigned long, unsigned long)
- ) { text_modified_handler = make_mfp(object,eh); }
-
- void set_text_modified_handler (
- const any_function<void(unsigned long, unsigned long)>& eh
- ) { text_modified_handler = eh; }
-
- private:
-
- void on_user_event (
- int num
- );
-
- void timer_action (
- );
- /*!
- ensures
- - flips the state of show_cursor
- !*/
-
- void compute_bg_rects (
- );
-
- void compute_total_rect (
- );
-
- void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- );
-
- void on_focus_lost (
- );
-
- void draw (
- const canvas& c
- ) const;
-
- rectangle get_text_rect (
- unsigned long row,
- unsigned long col
- ) const;
-
- rectangle get_bg_rect (
- unsigned long row,
- unsigned long col
- ) const;
-
- struct data_type
- {
- data_type(): text_color(0,0,0), bg_color(255,255,255),
- first(0), is_editable(true)
- {}
-
- dlib::ustring text;
- rgb_pixel text_color;
- rgb_pixel bg_color;
- rectangle bg_rect;
- dlib::ustring::size_type first;
- bool is_editable;
- };
-
- void drop_input_focus (
- );
-
- void move_cursor (
- long row,
- long col,
- long new_cursor_pos
- );
-
- array2d<data_type> grid;
- array<unsigned long> col_width;
- array<unsigned long> row_height;
- bool has_focus;
- long active_col;
- long active_row;
- long cursor_pos;
- bool show_cursor;
- bool recent_cursor_move;
- timer<text_grid> cursor_timer;
- rgb_pixel border_color_;
- any_function<void(unsigned long, unsigned long)> text_modified_handler;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class image_display : public scrollable_region
- {
- /*!
- INITIAL VALUE
- - img.size() == 0
- - overlay_rects.size() == 0
- - overlay_lines.size() == 0
- - drawing_rect == false
- - rect_is_selected == false
-
- CONVENTION
- - img == the image this object displays
- - overlay_rects == the overlay rectangles this object displays
- - overlay_lines == the overlay lines this object displays
-
- - if (drawing_rect) then
- - the user is drawing a rectangle on the screen and is
- thus holding down CTRL and the left mouse button.
- - rect_anchor == the point on the screen where the user
- clicked to begin drawing the rectangle.
- - rect_to_draw == the rectangle which should appear on the screen.
-
- - if (rect_is_selected) then
- - selected_rect == the index in overlay_rects of the user selected
- rectangle.
- - last_right_click_pos == the last place we saw the user right click
- the mouse.
- - parts_menu.is_enabled() == true
- - if (it is actually a part of this rect that is selected) then
- - selected_part_name == the name of the part in overlay_rects[selected_rect].parts
- that is selected.
- - else
- - selected_part_name.size() == 0
- - else
- - parts_menu.is_enabled() == false
- - selected_part_name.size() == 0
-
- - if (moving_overlay) then
- - moving_rect == the index in overlay_rects that the move applies to.
- - if (moving_what == MOVING_PART) then
- - moving_part_name == the name of the part in
- overlay_rects[moving_rect] that is being moved around with the
- mouse.
- - else
- - moving_what will tell us which side of the rectangle in
- overlay_rects[moving_rect] is being moved by the mouse.
- !*/
-
- public:
-
- image_display(
- drawable_window& w
- );
-
- ~image_display(
- );
-
- template <
- typename image_type
- >
- void set_image (
- const image_type& new_img
- )
- {
- auto_mutex M(m);
-
- // if the new image has a different size when compared to the previous image
- // then we should readjust the total rectangle size.
- if (num_rows(new_img) != img.nr() || num_columns(new_img) != img.nc())
- {
- if (zoom_in_scale != 1)
- set_total_rect_size(num_columns(new_img)*zoom_in_scale, num_rows(new_img)*zoom_in_scale);
- else
- set_total_rect_size(num_columns(new_img)/zoom_out_scale, num_rows(new_img)/zoom_out_scale);
- }
- else
- {
- parent.invalidate_rectangle(rect);
- }
-
- highlighted_rect = std::numeric_limits<unsigned long>::max();
- rect_is_selected = false;
- parts_menu.disable();
- assign_image_scaled(img,new_img);
- }
-
- virtual void set_pos (
- long x,
- long y
- )
- {
- auto_mutex lock(m);
- scrollable_region::set_pos(x,y);
- parts_menu.set_rect(rect);
- }
-
- virtual void set_size (
- unsigned long width,
- unsigned long height
- )
- {
- auto_mutex lock(m);
- scrollable_region::set_size(width,height);
- parts_menu.set_rect(rect);
- }
-
- struct overlay_rect
- {
- overlay_rect() :crossed_out(false) { assign_pixel(color, 0);}
-
- template <typename pixel_type>
- overlay_rect(const rectangle& r, pixel_type p)
- : rect(r),crossed_out(false) { assign_pixel(color, p); }
-
- template <typename pixel_type>
- overlay_rect(const rectangle& r, pixel_type p, const std::string& l)
- : rect(r),label(l),crossed_out(false) { assign_pixel(color, p); }
-
- template <typename pixel_type>
- overlay_rect(const rectangle& r, pixel_type p, const std::string& l, const std::map<std::string,point>& parts_)
- : rect(r),label(l),parts(parts_),crossed_out(false) { assign_pixel(color, p); }
-
- rectangle rect;
- rgb_alpha_pixel color;
- std::string label;
- std::map<std::string,point> parts;
- bool crossed_out;
- };
-
- struct overlay_line
- {
- overlay_line() { assign_pixel(color, 0);}
-
- template <typename pixel_type>
- overlay_line(const point& p1_, const point& p2_, pixel_type p)
- : p1(p1_), p2(p2_) { assign_pixel(color, p); }
-
- point p1;
- point p2;
- rgb_alpha_pixel color;
- };
-
- struct overlay_circle
- {
- overlay_circle():radius(0) { assign_pixel(color, 0);}
-
- template <typename pixel_type>
- overlay_circle(const point& center_, const int radius_, pixel_type p)
- : center(center_), radius(radius_) { assign_pixel(color, p); }
-
- template <typename pixel_type>
- overlay_circle(const point& center_, const int radius_, pixel_type p, const std::string& l)
- : center(center_), radius(radius_), label(l) { assign_pixel(color, p); }
-
- point center;
- int radius;
- rgb_alpha_pixel color;
- std::string label;
- };
-
- void add_overlay (
- const overlay_rect& overlay
- );
-
- void add_overlay (
- const overlay_line& overlay
- );
-
- void add_overlay (
- const overlay_circle& overlay
- );
-
- void add_overlay (
- const std::vector<overlay_rect>& overlay
- );
-
- void add_overlay (
- const std::vector<overlay_line>& overlay
- );
-
- void add_overlay (
- const std::vector<overlay_circle>& overlay
- );
-
- void clear_overlay (
- );
-
- rectangle get_image_display_rect (
- ) const;
-
- std::vector<overlay_rect> get_overlay_rects (
- ) const;
-
- void set_default_overlay_rect_label (
- const std::string& label
- );
-
- std::string get_default_overlay_rect_label (
- ) const;
-
- void set_default_overlay_rect_color (
- const rgb_alpha_pixel& color
- );
-
- rgb_alpha_pixel get_default_overlay_rect_color (
- ) const;
-
- template <
- typename T
- >
- void set_overlay_rects_changed_handler (
- T& object,
- void (T::*event_handler_)()
- )
- {
- auto_mutex M(m);
- event_handler = make_mfp(object,event_handler_);
- }
-
- void set_overlay_rects_changed_handler (
- const any_function<void()>& event_handler_
- )
- {
- auto_mutex M(m);
- event_handler = event_handler_;
- }
-
- template <
- typename T
- >
- void set_overlay_rect_selected_handler (
- T& object,
- void (T::*event_handler_)(const overlay_rect& orect)
- )
- {
- auto_mutex M(m);
- orect_selected_event_handler = make_mfp(object,event_handler_);
- }
-
- void set_overlay_rect_selected_handler (
- const any_function<void(const overlay_rect& orect)>& event_handler_
- )
- {
- auto_mutex M(m);
- orect_selected_event_handler = event_handler_;
- }
-
- template <
- typename T
- >
- void set_image_clicked_handler (
- T& object,
- void (T::*event_handler_)(const point& p, bool is_double_click, unsigned long btn)
- )
- {
- auto_mutex M(m);
- image_clicked_handler = make_mfp(object,event_handler_);
- }
-
- void set_image_clicked_handler (
- const any_function<void(const point& p, bool is_double_click, unsigned long btn)>& event_handler_
- )
- {
- auto_mutex M(m);
- image_clicked_handler = event_handler_;
- }
-
- void add_labelable_part_name (
- const std::string& name
- );
-
- void clear_labelable_part_names (
- );
-
- void enable_overlay_editing (
- ) { auto_mutex M(m); overlay_editing_enabled = true; }
-
- void disable_overlay_editing (
- )
- {
- auto_mutex M(m);
- overlay_editing_enabled = false;
- rect_is_selected = false;
- drawing_rect = false;
- parent.invalidate_rectangle(rect);
- }
-
- bool overlay_editing_is_enabled (
- ) const { auto_mutex M(m); return overlay_editing_enabled; }
-
- private:
-
- void draw (
- const canvas& c
- ) const;
-
- void on_wheel_up (
- unsigned long state
- );
-
- void on_wheel_down (
- unsigned long state
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void on_mouse_up (
- unsigned long btn,
- unsigned long state,
- long x,
- long y
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- void on_part_add (
- const std::string& part_name
- );
-
- rectangle get_rect_on_screen (
- unsigned long idx
- ) const;
-
- rectangle get_rect_on_screen (
- rectangle orect
- ) const;
-
- rgb_alpha_pixel invert_pixel (const rgb_alpha_pixel& p) const
- { return rgb_alpha_pixel(255-p.red, 255-p.green, 255-p.blue, p.alpha); }
-
- virtual int next_free_user_event_number (
- ) const { return scrollable_region::next_free_user_event_number()+1; }
- // The reason for using user actions here rather than just having the timer just call
- // what it needs directly is to avoid a potential deadlock during destruction of this widget.
- void timer_event_unhighlight_rect()
- {
- highlight_timer.stop();
- parent.trigger_user_event(this,scrollable_region::next_free_user_event_number());
- }
- void on_user_event (int num)
- {
- // ignore this user event if it isn't for us
- if (num != scrollable_region::next_free_user_event_number())
- return;
- if (highlighted_rect < overlay_rects.size())
- {
- highlighted_rect = std::numeric_limits<unsigned long>::max();
- parent.invalidate_rectangle(rect);
- }
- }
-
-
- array2d<rgb_alpha_pixel> img;
-
-
- std::vector<overlay_rect> overlay_rects;
- std::vector<overlay_line> overlay_lines;
- std::vector<overlay_circle> overlay_circles;
-
- long zoom_in_scale;
- long zoom_out_scale;
- bool drawing_rect;
- point rect_anchor;
- rectangle rect_to_draw;
- bool rect_is_selected;
- std::string selected_part_name;
- unsigned long selected_rect;
- rgb_alpha_pixel default_rect_color;
- std::string default_rect_label;
- any_function<void()> event_handler;
- any_function<void(const overlay_rect& orect)> orect_selected_event_handler;
- any_function<void(const point& p, bool is_double_click, unsigned long btn)> image_clicked_handler;
- popup_menu_region parts_menu;
- point last_right_click_pos;
- const double part_width;
- std::set<std::string> part_names;
- bool overlay_editing_enabled;
- timer<image_display> highlight_timer;
- unsigned long highlighted_rect;
- bool holding_shift_key;
-
- bool moving_overlay;
- unsigned long moving_rect;
- enum {
- MOVING_RECT_LEFT,
- MOVING_RECT_TOP,
- MOVING_RECT_RIGHT,
- MOVING_RECT_BOTTOM,
- MOVING_PART
- } moving_what;
- std::string moving_part_name;
-
- // restricted functions
- image_display(image_display&); // copy constructor
- image_display& operator=(image_display&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class perspective_display : public drawable, noncopyable
- {
- public:
-
- perspective_display(
- drawable_window& w
- );
-
- ~perspective_display(
- );
-
- virtual void set_size (
- unsigned long width,
- unsigned long height
- );
-
- struct overlay_line
- {
- overlay_line() { assign_pixel(color, 0);}
-
- overlay_line(const vector<double>& p1_, const vector<double>& p2_)
- : p1(p1_), p2(p2_) { assign_pixel(color, 255); }
-
- template <typename pixel_type>
- overlay_line(const vector<double>& p1_, const vector<double>& p2_, pixel_type p)
- : p1(p1_), p2(p2_) { assign_pixel(color, p); }
-
- vector<double> p1;
- vector<double> p2;
- rgb_pixel color;
- };
-
- struct overlay_dot
- {
- overlay_dot() { assign_pixel(color, 0);}
-
- overlay_dot(const vector<double>& p_)
- : p(p_) { assign_pixel(color, 255); }
-
- template <typename pixel_type>
- overlay_dot(const vector<double>& p_, pixel_type color_)
- : p(p_) { assign_pixel(color, color_); }
-
- vector<double> p;
- rgb_pixel color;
- };
-
-
- void add_overlay (
- const std::vector<overlay_line>& overlay
- );
-
- void add_overlay (
- const std::vector<overlay_dot>& overlay
- );
-
- void clear_overlay (
- );
-
- template <
- typename T
- >
- void set_dot_double_clicked_handler (
- T& object,
- void (T::*event_handler_)(const vector<double>&)
- )
- {
- auto_mutex M(m);
- dot_clicked_event_handler = make_mfp(object,event_handler_);
- }
-
- void set_dot_double_clicked_handler (
- const any_function<void(const vector<double>&)>& event_handler_
- );
-
- private:
-
- void draw (
- const canvas& c
- ) const;
-
- void on_wheel_up (
- unsigned long state
- );
-
- void on_wheel_down (
- unsigned long state
- );
-
- void on_mouse_down (
- unsigned long btn,
- unsigned long state,
- long x,
- long y,
- bool is_double_click
- );
-
- void on_mouse_move (
- unsigned long state,
- long x,
- long y
- );
-
- static bool compare_second (
- const std::pair<overlay_dot,float>& a,
- const std::pair<overlay_dot,float>& b
- ) { return a.second < b.second; }
-
-
- point last;
- std::vector<overlay_line> overlay_lines;
- std::vector<overlay_dot> overlay_dots;
-
- camera_transform tform;
- vector<double> sum_pts;
- vector<double> max_pts;
- any_function<void(const vector<double>&)> dot_clicked_event_handler;
- mutable array2d<float> depth;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class perspective_window : public drawable_window, noncopyable
- {
- public:
-
- typedef perspective_display::overlay_line overlay_line;
- typedef perspective_display::overlay_dot overlay_dot;
-
- perspective_window(
- ) : disp(*this)
- {
- set_size(100,100);
- on_window_resized();
- show();
- }
-
- perspective_window(
- const std::vector<dlib::vector<double> >& point_cloud
- ) :
- disp(*this)
- {
- set_size(100,100);
- on_window_resized();
- add_overlay(point_cloud);
- show();
- }
-
- perspective_window(
- const std::vector<dlib::vector<double> >& point_cloud,
- const std::string& title
- ) :
- disp(*this)
- {
- set_size(100,100);
- on_window_resized();
- add_overlay(point_cloud);
- set_title(title);
- show();
- }
-
- ~perspective_window(
- )
- {
- // You should always call close_window() in the destructor of window
- // objects to ensure that no events will be sent to this window while
- // it is being destructed.
- close_window();
- }
-
- void add_overlay (
- const std::vector<overlay_line>& overlay
- )
- {
- disp.add_overlay(overlay);
- }
-
- void add_overlay (
- const std::vector<overlay_dot>& overlay
- )
- {
- disp.add_overlay(overlay);
- }
-
- void clear_overlay (
- )
- {
- disp.clear_overlay();
- }
-
- template <typename pixel_type>
- void add_overlay(const vector<double>& p1, const vector<double>& p2, pixel_type p)
- {
- add_overlay(std::vector<overlay_line>(1,overlay_line(p1,p2,p)));
- }
-
- void add_overlay(const std::vector<dlib::vector<double> >& d)
- {
- add_overlay(d, 255);
- }
-
- template <typename pixel_type>
- void add_overlay(const std::vector<dlib::vector<double> >& d, pixel_type p)
- {
- std::vector<overlay_dot> temp;
- temp.resize(d.size());
- for (unsigned long i = 0; i < temp.size(); ++i)
- temp[i] = overlay_dot(d[i], p);
-
- add_overlay(temp);
- }
-
- template <
- typename T
- >
- void set_dot_double_clicked_handler (
- T& object,
- void (T::*event_handler_)(const vector<double>&)
- )
- {
- disp.set_dot_double_clicked_handler(object,event_handler_);
- }
-
- void set_dot_double_clicked_handler (
- const any_function<void(const vector<double>&)>& event_handler_
- )
- {
- disp.set_dot_double_clicked_handler(event_handler_);
- }
-
- private:
-
- void on_window_resized(
- )
- {
- drawable_window::on_window_resized();
- unsigned long width, height;
- get_size(width,height);
- disp.set_pos(0,0);
- disp.set_size(width, height);
- }
-
- perspective_display disp;
- };
-
-// ----------------------------------------------------------------------------------------
-
- class image_window : public drawable_window
- {
- public:
-
- typedef image_display::overlay_rect overlay_rect;
- typedef image_display::overlay_line overlay_line;
- typedef image_display::overlay_circle overlay_circle;
-
- image_window(
- );
-
- template < typename image_type >
- image_window(
- const image_type& img
- ) :
- gui_img(*this),
- window_has_closed(false),
- have_last_click(false),
- mouse_btn(0),
- clicked_signaler(this->wm),
- have_last_keypress(false),
- tie_input_events(false)
- {
- gui_img.set_image_clicked_handler(*this, &image_window::on_image_clicked);
- gui_img.disable_overlay_editing();
- set_image(img);
- show();
- }
-
- template < typename image_type >
- image_window(
- const image_type& img,
- const std::string& title
- ) :
- gui_img(*this),
- window_has_closed(false),
- have_last_click(false),
- mouse_btn(0),
- clicked_signaler(this->wm),
- have_last_keypress(false),
- tie_input_events(false)
- {
- gui_img.set_image_clicked_handler(*this, &image_window::on_image_clicked);
- gui_img.disable_overlay_editing();
- set_image(img);
- set_title(title);
- show();
- }
-
-
- ~image_window(
- );
-
- template < typename image_type >
- void set_image (
- const image_type& img
- )
- {
- const unsigned long padding = scrollable_region_style_default().get_border_size();
- auto_mutex M(wm);
- gui_img.set_image(img);
-
- // Only ever mess with the size of the window if the user is giving us an image
- // that is a different size. Otherwise we assume that they will have already
- // sized the window to whatever they feel is reasonable for an image of the
- // current size.
- if (previous_image_size != get_rect(img))
- {
- const rectangle r = gui_img.get_image_display_rect();
- if (image_rect != r)
- {
- // set the size of this window to match the size of the input image
- set_size(r.width()+padding*2,r.height()+padding*2);
-
- // call this to make sure everything else is setup properly
- on_window_resized();
-
- image_rect = r;
- }
- previous_image_size = get_rect(img);
- }
- }
-
- void add_overlay (
- const overlay_rect& overlay
- );
-
- template <typename pixel_type>
- void add_overlay(const rectangle& r, pixel_type p)
- { add_overlay(image_display::overlay_rect(r,p)); }
-
- void add_overlay(const rectangle& r)
- { add_overlay(image_display::overlay_rect(r,rgb_pixel(255,0,0))); }
-
- template <typename pixel_type>
- void add_overlay(const rectangle& r, pixel_type p, const std::string& l)
- { add_overlay(image_display::overlay_rect(r,p,l)); }
-
- template <typename pixel_type>
- void add_overlay(const std::vector<rectangle>& r, pixel_type p)
- {
- std::vector<overlay_rect> temp;
- temp.resize(r.size());
- for (unsigned long i = 0; i < temp.size(); ++i)
- temp[i] = overlay_rect(r[i], p);
-
- add_overlay(temp);
- }
-
- void add_overlay(const std::vector<rectangle>& r)
- { add_overlay(r, rgb_pixel(255,0,0)); }
-
- void add_overlay(
- const full_object_detection& object,
- const std::vector<std::string>& part_names
- )
- {
-
- add_overlay(overlay_rect(object.get_rect(), rgb_pixel(255,0,0)));
-
- std::vector<overlay_circle> temp;
- temp.reserve(object.num_parts());
- for (unsigned long i = 0; i < object.num_parts(); ++i)
- {
- if (object.part(i) != OBJECT_PART_NOT_PRESENT)
- {
- if (i < part_names.size())
- temp.push_back(overlay_circle(object.part(i), 7, rgb_pixel(0,255,0), part_names[i]));
- else
- temp.push_back(overlay_circle(object.part(i), 7, rgb_pixel(0,255,0)));
- }
- }
-
- add_overlay(temp);
- }
-
- void add_overlay(
- const full_object_detection& object
- )
- {
- std::vector<std::string> part_names;
- add_overlay(object, part_names);
- }
-
- void add_overlay(
- const std::vector<full_object_detection>& objects,
- const std::vector<std::string>& part_names
- )
- {
- std::vector<overlay_rect> rtemp;
- rtemp.reserve(objects.size());
- for (unsigned long i = 0; i < objects.size(); ++i)
- {
- rtemp.push_back(overlay_rect(objects[i].get_rect(), rgb_pixel(255,0,0)));
- }
-
- add_overlay(rtemp);
-
- std::vector<overlay_circle> temp;
-
- for (unsigned long i = 0; i < objects.size(); ++i)
- {
- for (unsigned long j = 0; j < objects[i].num_parts(); ++j)
- {
- if (objects[i].part(j) != OBJECT_PART_NOT_PRESENT)
- {
- if (j < part_names.size())
- temp.push_back(overlay_circle(objects[i].part(j), 7, rgb_pixel(0,255,0),part_names[j]));
- else
- temp.push_back(overlay_circle(objects[i].part(j), 7, rgb_pixel(0,255,0)));
- }
- }
- }
-
- add_overlay(temp);
- }
-
- void add_overlay(
- const std::vector<full_object_detection>& objects
- )
- {
- std::vector<std::string> part_names;
- add_overlay(objects, part_names);
- }
-
- void add_overlay (
- const overlay_line& overlay
- );
-
- void add_overlay (
- const overlay_circle& overlay
- );
-
- template <typename pixel_type>
- void add_overlay(const point& p1, const point& p2, pixel_type p)
- { add_overlay(image_display::overlay_line(p1,p2,p)); }
-
- void add_overlay (
- const std::vector<overlay_rect>& overlay
- );
-
- void add_overlay (
- const std::vector<overlay_line>& overlay
- );
-
- void add_overlay (
- const std::vector<overlay_circle>& overlay
- );
-
- void clear_overlay (
- );
-
- bool get_next_double_click (
- point& p,
- unsigned long& mouse_button
- );
-
- void tie_events (
- );
-
- void untie_events (
- );
-
- bool events_tied (
- ) const;
-
- bool get_next_double_click (
- point& p
- )
- {
- unsigned long mouse_button;
- return get_next_double_click(p, mouse_button);
- }
-
- bool get_next_keypress (
- unsigned long& key,
- bool& is_printable,
- unsigned long& state
- );
-
- bool get_next_keypress (
- unsigned long& key,
- bool& is_printable
- )
- {
- unsigned long state;
- return get_next_keypress(key,is_printable,state);
- }
-
- private:
-
- virtual base_window::on_close_return_code on_window_close(
- );
-
- void on_window_resized(
- );
-
- void on_image_clicked (
- const point& p,
- bool is_double_click,
- unsigned long btn
- );
-
- virtual void on_keydown (
- unsigned long key,
- bool is_printable,
- unsigned long state
- );
-
- // restricted functions
- image_window(image_window&);
- image_window& operator= (image_window&);
-
- image_display gui_img;
- rectangle image_rect;
- rectangle previous_image_size;
- bool window_has_closed;
- bool have_last_click;
- point last_clicked_point;
- unsigned long mouse_btn;
- rsignaler clicked_signaler;
-
- bool have_last_keypress;
- unsigned long next_key;
- bool next_is_printable;
- unsigned long next_state;
- bool tie_input_events;
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "widgets.cpp"
-#endif
-
-#endif // DLIB_WIDGETs_
-
diff --git a/ml/dlib/dlib/gui_widgets/widgets_abstract.h b/ml/dlib/dlib/gui_widgets/widgets_abstract.h
deleted file mode 100644
index 2b4dc4486..000000000
--- a/ml/dlib/dlib/gui_widgets/widgets_abstract.h
+++ /dev/null
@@ -1,3461 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net), Keita Mochizuki
-// License: Boost Software License See LICENSE.txt for the full license.
-
-#undef DLIB_WIDGETs_ABSTRACT_
-#ifdef DLIB_WIDGETs_ABSTRACT_
-
-#include "fonts_abstract.h"
-#include "drawable_abstract.h"
-#include "base_widgets_abstract.h"
-
-#include "../gui_core.h"
-#include <string>
-#include <map>
-#include "../interfaces/enumerable.h"
-#include "style_abstract.h"
-#include "../image_processing/full_object_detection_abstract.h"
-
-namespace dlib
-{
-
- /*!
- GENERAL REMARKS
- This component is a collection of various windowing widgets such as buttons,
- labels, text boxes, and so on. This component also includes the drawable
- interface, drawable_window, and font handling objects. The file you are
- currently viewing defines all the high level graphical widgets which are
- provided by this component that can appear in a drawable_window. To view
- the specifications for the other members of this component look at
- fonts_abstract.h, base_widgets_abstract.h, and drawable_abstract.h
-
- THREAD SAFETY
- All objects and functions defined in this file are thread safe. You may
- call them from any thread without serializing access to them.
-
- EVENT HANDLERS
- Note that all event handlers, including the user registered callback
- functions, are executed in the event handling thread. Additionally,
- the drawable::m mutex will always be locked while these event handlers
- are running. Also, don't rely on get_thread_id() always returning the
- same ID from inside event handlers.
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // function open_file_box(), open_existing_file_box(), and save_file_box()
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- void open_file_box (
- T& object,
- void (T::*event_handler)(const std::string&)
- );
- /*!
- requires
- - event_handler == a valid pointer to a member function of object T.
- ensures
- - Displays a window titled "Open File" that will allow the user to select a
- file.
- - The displayed window will start out showing the directory get_current_dir()
- (i.e. it starts in the current working directory)
- - The event_handler function is called on object if the user selects
- a file. If the user closes the window without selecting a file
- then nothing occurs.
- !*/
-
- void open_file_box (
- const any_function<void(const std::string&)>& event_handler
- );
- /*!
- ensures
- - Displays a window titled "Open File" that will allow the user to select a
- file.
- - The displayed window will start out showing the directory get_current_dir()
- (i.e. it starts in the current working directory)
- - The event_handler function is called if the user selects
- a file. If the user closes the window without selecting a file
- then nothing occurs.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- void open_existing_file_box (
- T& object,
- void (T::*event_handler)(const std::string&)
- );
- /*!
- requires
- - event_handler == a valid pointer to a member function of object T.
- ensures
- - Displays a window titled "Open File" that will allow the user to select
- a file. But only a file that already exists.
- - The displayed window will start out showing the directory get_current_dir()
- (i.e. it starts in the current working directory)
- - The event_handler function is called on object if the user selects
- a file. If the user closes the window without selecting a file
- then nothing occurs.
- !*/
-
- void open_existing_file_box (
- const any_function<void(const std::string&)>& event_handler
- );
- /*!
- ensures
- - Displays a window titled "Open File" that will allow the user to select
- a file. But only a file that already exists.
- - The displayed window will start out showing the directory get_current_dir()
- (i.e. it starts in the current working directory)
- - The event_handler function is called if the user selects
- a file. If the user closes the window without selecting a file
- then nothing occurs.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- void save_file_box (
- T& object,
- void (T::*event_handler)(const std::string&)
- );
- /*!
- requires
- - event_handler == a valid pointer to a member function of object T.
- ensures
- - Displays a window titled "Save File" that will allow the user to select
- a file.
- - The displayed window will start out showing the directory get_current_dir()
- (i.e. it starts in the current working directory)
- - The event_handler function is called on object if the user selects
- a file. If the user closes the window without selecting a file
- then nothing occurs.
- !*/
-
- void save_file_box (
- const any_function<void(const std::string&)>& event_handler
- );
- /*!
- ensures
- - Displays a window titled "Save File" that will allow the user to select
- a file.
- - The displayed window will start out showing the directory get_current_dir()
- (i.e. it starts in the current working directory)
- - The event_handler function is called if the user selects
- a file. If the user closes the window without selecting a file
- then nothing occurs.
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // function message_box()
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- void message_box (
- const std::string& title,
- const std::string& message
- );
- /*!
- ensures
- - displays a message box with the given title and message. It will have a
- single button and when the user clicks it the message box will go away.
- - this function does not block but instead returns immediately.
- !*/
-
- void message_box_blocking (
- const std::string& title,
- const std::string& message
- );
- /*!
- ensures
- - displays a message box with the given title and message. It will have a
- single button and when the user clicks it the message box will go away.
- - this function blocks until the user clicks on the message box and
- causes it to go away.
- !*/
-
- template <
- typename T
- >
- void message_box (
- const std::string& title,
- const std::string& message,
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler == a valid pointer to a member function of object T.
- ensures
- - Displays a message box with the given title and message. It will have a
- single button and when the user clicks it the message box will go away.
- - The event_handler function is called on object when the user clicks
- ok or otherwise closes the message box window.
- - this function does not block but instead returns immediately.
- !*/
-
- void message_box (
- const std::string& title,
- const std::string& message,
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - Displays a message box with the given title and message. It will have a
- single button and when the user clicks it the message box will go away.
- - The event_handler function is called when the user clicks
- ok or otherwise closes the message box window.
- - this function does not block but instead returns immediately.
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class label
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class label : public drawable
- {
- /*!
- INITIAL VALUE
- text() == ""
- the text color will be black
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple text label. The size of the label
- is automatically set to be just big enough to contain its text.
- !*/
-
- public:
-
- label(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~label(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_text (const std::wstring& text);
- void set_text (const dlib::ustring& text);
- void set_text (
- const std::string& text
- );
- /*!
- ensures
- - #text() == text
- throws
- - std::bad_alloc
- !*/
-
- const std::wstring wtext () const;
- const dlib::ustring utext () const;
- const std::string text (
- ) const;
- /*!
- ensures
- - returns the text of this label
- throws
- - std::bad_alloc
- !*/
-
- void set_text_color (
- const rgb_pixel color
- );
- /*!
- ensures
- - #text_color() == color
- !*/
-
- const rgb_pixel text_color (
- ) const;
- /*!
- ensures
- - returns the color used to draw the text in this widget
- !*/
-
- private:
-
- // restricted functions
- label(label&); // copy constructor
- label& operator=(label&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class toggle_button
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class toggle_button : public button_action
- {
- /*!
- INITIAL VALUE
- name() == ""
- is_checked() == false
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple two state toggle button. Is is either
- in the checked or unchecked state and when a user clicks on it it toggles its
- state.
-
- When this object is disabled it means it will not respond to user clicks.
- !*/
-
- public:
-
- toggle_button(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~toggle_button(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_name (const std::wstring& name);
- void set_name (const dlib::ustring& name);
- void set_name (
- const std::string& name
- );
- /*!
- ensures
- - #name() == name
- - this toggle_button has been resized such that it is big enough to contain
- the new name.
- throws
- - std::bad_alloc
- !*/
-
- void set_size (
- unsigned long width_,
- unsigned long height_
- );
- /*!
- ensures
- - if (width and height are big enough to contain the name of this button) then
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this button stays the
- same but its width and height are modified
- !*/
-
- void set_tooltip_text (const std::wstring& text);
- void set_tooltip_text (const dlib::ustring& text);
- void set_tooltip_text (
- const std::string& text
- );
- /*!
- ensures
- - #tooltip_text() == text
- - enables the tooltip for this toggle_button
- !*/
-
- const dlib::ustring tooltip_utext () const;
- const std::wstring tooltip_wtext () const;
- const std::string tooltip_text (
- ) const;
- /*!
- ensures
- - returns the text that is displayed in the tooltip for this toggle_button
- !*/
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style
- );
- /*!
- requires
- - style_type == a type that inherits from toggle_button_style
- ensures
- - this toggle_button object will draw itself using the given
- button style
- !*/
-
- bool is_checked (
- ) const;
- /*!
- ensures
- - if (this box is currently checked) then
- - returns true
- - else
- - returns false
- !*/
-
- const std::wstring wname () const;
- const dlib::ustring uname () const;
- const std::string name (
- ) const;
- /*!
- ensures
- - returns the name of this toggle_button. The name is a string
- that appears to the right of the actual check box.
- throws
- - std::bad_alloc
- !*/
-
- void set_checked (
- );
- /*!
- ensures
- - #is_checked() == true
- !*/
-
- void set_unchecked (
- );
- /*!
- ensures
- - #is_checked() == false
- !*/
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the toggle_button is
- toggled by the user.
- - this event is NOT triggered by calling set_checked() or set_unchecked().
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_click_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the toggle_button is
- toggled by the user.
- - this event is NOT triggered by calling set_checked() or set_unchecked().
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler)(toggle_button& self)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T.
- ensures
- - the event_handler function is called on object when the toggle_button is
- toggled by the user. self will be a reference to the toggle_button object
- that the user clicked.
- - this event is NOT triggered by calling set_checked() or set_unchecked().
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_sourced_click_handler (
- const any_function<void(toggle_button& self)>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the toggle_button is
- toggled by the user. self will be a reference to the toggle_button object
- that the user clicked.
- - this event is NOT triggered by calling set_checked() or set_unchecked().
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- toggle_button(toggle_button&); // copy constructor
- toggle_button& operator=(toggle_button&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class text_field
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_field : public drawable
- {
- /*!
- INITIAL VALUE
- - text() == ""
- - width() == 10
- - height() == a height appropriate for the font used. The text color will
- be black.
- - has_input_focus() == false
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple one line text input field.
- !*/
-
- public:
-
- text_field(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~text_field(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style
- );
- /*!
- requires
- - style_type == a type that inherits from text_field_style
- ensures
- - this text_field object will draw itself using the given
- text field style
- !*/
-
- void set_text (const std::wstring& text);
- void set_text (const dlib::ustring& text);
- void set_text (
- const std::string& text
- );
- /*!
- requires
- - text.find_first_of('\n') == std::string::npos
- (i.e. there aren't any new lines in text)
- ensures
- - #text() == text
- throws
- - std::bad_alloc
- !*/
-
- const std::wstring wtext () const;
- const dlib::ustring utext () const;
- const std::string text (
- ) const;
- /*!
- ensures
- - returns the text of this text_field
- throws
- - std::bad_alloc
- !*/
-
- void set_width (
- unsigned long width_
- );
- /*!
- ensures
- - if (width >= 10) then
- - #width() == width_
- - #height() == height()
- - #top() == top()
- - #left() == left()
- - i.e. The width of this drawable is set to the given width but
- nothing else changes.
- !*/
-
- void give_input_focus (
- );
- /*!
- ensures
- - #has_input_focus() == true
- !*/
-
- bool has_input_focus (
- );
- /*!
- ensures
- - Returns true if this txt field has input keyboard focus. If this
- is the case then it means that when the user types on the keyboard
- the output will appear inside the text field.
- !*/
-
- void select_all_text (
- );
- /*!
- ensures
- - causes all the text in the text field to become selected.
- (note that it doesn't give input focus)
- !*/
-
- void set_text_color (
- const rgb_pixel color
- );
- /*!
- ensures
- - #text_color() == color
- !*/
-
- const rgb_pixel text_color (
- ) const;
- /*!
- ensures
- - returns the color used to draw the text in this widget
- !*/
-
- void set_background_color (
- const rgb_pixel color
- );
- /*!
- ensures
- - #background_color() == color
- !*/
-
- const rgb_pixel background_color (
- ) const;
- /*!
- ensures
- - returns the color used to fill in the background of this widget
- !*/
-
- template <
- typename T
- >
- void set_text_modified_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the text
- in this text_field is modified by the user.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_text_modified_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the text in this text_field
- is modified by the user.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_enter_key_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when this text field
- has input focus and the user hits the enter key on their keyboard.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_enter_key_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when this text field has input
- focus and the user hits the enter key on their keyboard.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_focus_lost_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when this object
- loses input focus due to the user clicking outside the text field
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_focus_lost_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when this object loses input
- focus due to the user clicking outside the text field
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- text_field(text_field&); // copy constructor
- text_field& operator=(text_field&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class text_box
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class text_box : public scrollable_region
- {
- /*!
- INITIAL VALUE
- - text() == ""
- - The text color will be black.
- - width() == 100
- - height() == 100
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple multi-line text input box.
- !*/
-
- public:
-
- text_box(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~text_box(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style
- );
- /*!
- requires
- - style_type == a type that inherits from text_box_style
- ensures
- - this text_box object will draw itself using the given
- text box style
- !*/
-
- void set_text (const std::wstring& text);
- void set_text (const dlib::ustring& text);
- void set_text (
- const std::string& text
- );
- /*!
- ensures
- - #text() == text
- throws
- - std::bad_alloc
- !*/
-
- const std::wstring wtext () const;
- const dlib::ustring utext () const;
- const std::string text (
- ) const;
- /*!
- ensures
- - returns the text of this text_box
- throws
- - std::bad_alloc
- !*/
-
- void set_size (
- unsigned long width,
- unsigned long height
- );
- /*!
- ensures
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this widget stays the
- same but its width and height are modified
- !*/
-
- void set_text_color (
- const rgb_pixel color
- );
- /*!
- ensures
- - #text_color() == color
- !*/
-
- const rgb_pixel text_color (
- ) const;
- /*!
- ensures
- - returns the color used to draw the text in this widget
- !*/
-
- void set_background_color (
- const rgb_pixel color
- );
- /*!
- ensures
- - #background_color() == color
- !*/
-
- const rgb_pixel background_color (
- ) const;
- /*!
- ensures
- - returns the color used to fill in the background of this widget
- !*/
-
- template <
- typename T
- >
- void set_text_modified_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the text
- in this text_box is modified by the user.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_text_modified_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the text in this text_box
- is modified by the user.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_enter_key_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when this text box
- has input focus and the user hits the enter key on their keyboard.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_enter_key_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when this text box has input
- focus and the user hits the enter key on their keyboard.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_focus_lost_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when this object
- loses input focus due to the user clicking outside the text box
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_focus_lost_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when this object loses input
- focus due to the user clicking outside the text box
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- text_box(text_box&); // copy constructor
- text_box& operator=(text_box&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class check_box
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class check_box : public toggle_button
- {
- /*!
- This is just a toggle button with the style set to
- toggle_button_style_check_box.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class radio_button
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class radio_button : public toggle_button
- {
- /*!
- This is just a toggle button with the style set to
- toggle_button_style_radio_button.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class tabbed_display
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class tabbed_display : public drawable
- {
- /*!
- INITIAL VALUE
- number_of_tabs() == 1
- selected_tab() == 0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a row of tabs that are user selectable.
-
- When this object is disabled it means it will not respond to user clicks.
- !*/
-
- public:
-
- tabbed_display(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~tabbed_display(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_size (
- unsigned long width_,
- unsigned long height_
- );
- /*!
- ensures
- - if (width and height are big enough to contain the tabs) then
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this widget stays the
- same but its width and height are modified
- !*/
-
- void set_number_of_tabs (
- unsigned long num
- );
- /*!
- requires
- - num > 0
- ensures
- - #number_of_tabs() == num
- - no tabs have any widget_groups associated with them.
- - for all valid idx:
- - #tab_name(idx) == ""
- throws
- - std::bad_alloc
- !*/
-
- unsigned long selected_tab (
- ) const;
- /*!
- ensures
- - returns the index of the currently selected tab
- !*/
-
- unsigned long number_of_tabs (
- ) const;
- /*!
- ensures
- - returns the number of tabs in this tabbed_display
- !*/
-
- const std::wstring& tab_wname (unsigned long idx) const;
- const dlib::ustring& tab_uname (unsigned long idx) const;
- const std::string& tab_name (
- unsigned long idx
- ) const;
- /*!
- requires
- - idx < number_of_tabs()
- ensures
- - returns a const reference to the name of the tab given by idx
- !*/
-
- void set_tab_name (unsigned long idx, const std::wstring& new_name);
- void set_tab_name (unsigned long idx, const dlib::ustring& new_name);
- void set_tab_name (
- unsigned long idx,
- const std::string& new_name
- );
- /*!
- requires
- - idx < number_of_tabs()
- ensures
- - #tab_name(idx) == new_name
- throws
- - std::bad_alloc
- !*/
-
- void set_tab_group (
- unsigned long idx,
- widget_group& group
- );
- /*!
- requires
- - idx < number_of_tabs()
- ensures
- - if (is_hidden()) then
- - group.is_hidden() == true
- - else
- - whenever the tab with index idx is selected group.is_hidden() == false
- - whenever the tab with index idx is deselected group.is_hidden() == true
- - whenever the position of *this changes the position of group will be
- updated so that it is still inside the tabbed_display. The position of group
- will also be updated after this call to set_tab_group().
- - any previous calls to set_tab_group() with this index are overridden by this
- new call. (i.e. you can only have one widget_group associated with a single
- tab at a time)
- !*/
-
- void fit_to_contents (
- );
- /*!
- ensures
- - Adjusts the size this tabbed_display so that it nicely contains
- all of its widget_group objects.
- - does not change the position of this object.
- (i.e. the upper left corner of get_rect() remains at the same position)
- !*/
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler)(unsigned long new_idx, unsigned long old_idx)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - The event_handler function is called on object when the user clicks
- on a tab that isn't already selected. new_idx will give the index of
- the newly selected tab and old_idx will give the index of the tab
- that was previously selected.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_click_handler (
- const any_function<void(unsigned long new_idx, unsigned long old_idx)>& eh
- );
- /*!
- ensures
- - The event_handler function is called when the user clicks on a tab
- that isn't already selected. new_idx will give the index of the
- newly selected tab and old_idx will give the index of the tab that
- was previously selected.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- tabbed_display(tabbed_display&); // copy constructor
- tabbed_display& operator=(tabbed_display&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class named_rectangle
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class named_rectangle : public drawable
- {
- /*!
- INITIAL VALUE
- name() == ""
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple named rectangle.
- !*/
-
- public:
-
- named_rectangle(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~named_rectangle(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_size (
- unsigned long width_,
- unsigned long height_
- );
- /*!
- ensures
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this widget stays the
- same but its width and height are modified
- !*/
-
- void wrap_around (
- const rectangle& rect
- );
- /*!
- ensures
- - This object will be repositioned and sized so that it fits
- around the given rectangle.
- !*/
-
- void set_name (const std::wstring& name);
- void set_name (const dlib::ustring& name);
- void set_name (
- const std::string& name
- );
- /*!
- ensures
- - #name() == name
- throws
- - std::bad_alloc
- !*/
-
- const std::wstring wname () const;
- const dlib::ustring uname () const;
- const std::string name (
- ) const;
- /*!
- ensures
- - returns the name of this named_rectangle
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- named_rectangle(named_rectangle&); // copy constructor
- named_rectangle& operator=(named_rectangle&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class mouse_tracker
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class mouse_tracker : public draggable
- {
- /*!
- INITIAL VALUE
- draggable_area() == rectangle(0,0,500,500)
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple draggable box that displays the
- current location of the mouse.
-
- Also, if you hold shift and left click on the parent window then the
- mouse_tracker will place a single red pixel where you clicked and will
- display the mouse position relative to that point.
- !*/
-
- public:
-
- mouse_tracker(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~mouse_tracker(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- private:
-
- // restricted functions
- mouse_tracker(mouse_tracker&); // copy constructor
- mouse_tracker& operator=(mouse_tracker&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class list_box
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class list_box : public scrollable_region,
- public enumerable<const std::string>
- {
- /*!
- INITIAL VALUE
- multiple_select_enabled() == false
- size() == 0
-
- ENUMERATION ORDER
- The enumerator will iterate over the elements in the list_box from
- the 0th element to the (size()-1)th element. i.e. (*this)[0] to
- (*this)[size()-1].
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple textual list box. It contains a
- vertical list of strings which the user may select from.
- !*/
-
- public:
-
- list_box(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~list_box(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- template <
- typename style_type
- >
- void set_style (
- const style_type& style
- );
- /*!
- requires
- - style_type == a type that inherits from list_box_style
- ensures
- - this list_box object will draw itself using the given style
- !*/
-
- void set_size (
- unsigned long width_,
- unsigned long height_
- );
- /*!
- ensures
- - #width() == width_
- - #height() == height_
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this widget stays the
- same but its width and height are modified
- !*/
-
- bool is_selected (
- unsigned long index
- ) const;
- /*!
- requires
- - index < size()
- ensures
- - if (the item given by index is currently selected) then
- - returns true
- - else
- - returns false
- !*/
-
- void select (
- unsigned long index
- );
- /*!
- requires
- - index < size()
- ensures
- - #is_selected(index) == true
- !*/
-
- void unselect (
- unsigned long index
- );
- /*!
- requires
- - index < size()
- ensures
- - #is_selected(index) == false
- !*/
-
- template <typename T>
- void get_selected (
- T& list
- ) const;
- /*!
- requires
- - T == an implementation of dlib/queue/queue_kernel_abstract.h
- - T::type == unsigned long
- ensures
- - #list == a list of all the currently selected indices for this list_box.
- !*/
-
- unsigned long get_selected (
- ) const;
- /*!
- requires
- - multiple_select_enabled() == false
- ensures
- - if (there is currently something selected) then
- - returns the index of the selected item
- - else
- - returns size()
- !*/
-
- template <typename T>
- void load (
- const T& list
- );
- /*!
- requires
- - T == compatible with dlib::enumerable<std::string>
- ensures
- - #size() == list.size()
- - Copies all the strings from list into *this in the order in which they are enumerated.
- (i.e. The first one goes into (*this)[0], the second into (*this)[1], and so on...)
- !*/
-
- const std::string& operator[] (
- unsigned long index
- ) const;
- /*!
- requires
- - index < size()
- ensures
- - returns the name of the indexth item/row in this list box.
- !*/
-
- bool multiple_select_enabled (
- ) const;
- /*!
- ensures
- - if (this object will allow the user to select more than one item at a time) then
- - returns true
- - else
- - returns false
- !*/
-
- void enable_multiple_select (
- );
- /*!
- ensures
- - #multiple_select_enabled() == true
- !*/
-
- void disable_multiple_select (
- );
- /*!
- ensures
- - #multiple_select_enabled() == false
- !*/
-
- template <
- typename T
- >
- void set_double_click_handler (
- T& object,
- void (T::*event_handler)(unsigned long index)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T.
- ensures
- - The event_handler function is called on object when the user double
- clicks on one of the rows in this list box. index gives the row
- number for the item the user clicked.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_double_click_handler (
- const any_function<void(unsigned long index)>& event_handler
- );
- /*!
- ensures
- - The event_handler function is called when the user double clicks on
- one of the rows in this list box. index gives the row number for
- the item the user clicked.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_click_handler (
- T& object,
- void (T::*event_handler)(unsigned long index)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T.
- ensures
- - The event_handler function is called on object when the user
- clicks on one of the rows in this list box. index gives the row
- number for the item the user clicked. (Note that the second click
- in a double click triggers the double click handler above instead
- of this event)
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_click_handler (
- const any_function<void(unsigned long index)>& event_handler
- );
- /*!
- ensures
- - The event_handler function is called when the user clicks on one
- of the rows in this list box. index gives the row number for the
- item the user clicked. (Note that the second click in a double
- click triggers the double click handler above instead of this event)
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- list_box(list_box&); // copy constructor
- list_box& operator=(list_box&); // assignment operator
- };
-
- class wlist_box : public scrollable_region,
- public enumerable<const std::wstring>;
- /*!
- same as list_box except for std::wstring instead of std::string
- !*/
-
- class ulist_box : public scrollable_region,
- public enumerable<const dlib::ustring>;
- /*!
- same as list_box except for dlib::ustring instead of std::string
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // class menu_bar
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class menu_bar : public drawable
- {
- /*!
- INITIAL VALUE
- - number_of_menus() == 0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a menu bar that appears at the top of a
- window.
- !*/
-
- public:
-
- menu_bar(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~menu_bar(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_number_of_menus (
- unsigned long num
- );
- /*!
- ensures
- - #number_of_menus() == num
- !*/
-
- unsigned long number_of_menus (
- ) const;
- /*!
- ensures
- - returns the number of menus in this menu_bar
- !*/
-
- void set_menu_name (unsigned long idx, const std::wstring name, char underline_ch = '\0');
- void set_menu_name (unsigned long idx, const dlib::ustring name, char underline_ch = '\0');
- void set_menu_name (
- unsigned long idx,
- const std::string name,
- char underline_ch = '\0'
- );
- /*!
- requires
- - idx < number_of_menus()
- ensures
- - #menu_name(idx) == name
- - if (underline_ch is present in name) then
- - The menu with index idx will have the first underline_ch character
- in its name underlined and users will be able to activate the menu
- by hitting alt+underline_char
- !*/
-
- const std::wstring menu_wname (unsigned long idx) const;
- const dlib::ustring menu_uname (unsigned long idx) const;
- const std::string menu_name (
- unsigned long idx
- ) const;
- /*!
- requires
- - idx < number_of_menus()
- ensures
- - returns the name of the menu with index idx
- !*/
-
- popup_menu& menu (
- unsigned long idx
- );
- /*!
- requires
- - idx < number_of_menus()
- ensures
- - returns a non-const reference to the popup_menu for the menu with
- index idx.
- !*/
-
- const popup_menu& menu (
- unsigned long idx
- ) const;
- /*!
- requires
- - idx < number_of_menus()
- ensures
- - returns a const reference to the popup_menu for the menu with
- index idx.
- !*/
-
- private:
-
- // restricted functions
- menu_bar(menu_bar&); // copy constructor
- menu_bar& operator=(menu_bar&); // assignment operator
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename graph_type
- >
- class directed_graph_drawer : public zoomable_region
- {
- /*!
- REQUIREMENTS ON graph_type
- - must be an implementation of directed_graph/directed_graph_kernel_abstract.h
-
- INITIAL VALUE
- - get_graph().size() == 0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a graphical widget that allows the user to draw
- a directed graph.
-
- The user can create nodes by right clicking on the draw area and add
- edges by selecting a node (via left clicking on it) and then holding
- shift and clicking on the node that is to be the child node of the
- selected node.
- !*/
-
- public:
-
- directed_graph_drawer (
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~directed_graph_drawer (
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- const graph_type& graph (
- ) const;
- /*!
- requires
- - drawable::m is locked
- ensures
- - returns a const reference to the graph that this widget has been drawing
- !*/
-
- unsigned long number_of_nodes (
- ) const;
- /*!
- ensures
- - returns graph().number_of_nodes()
- !*/
-
- void clear_graph (
- );
- /*!
- ensures
- - #number_of_nodes() == 0
- !*/
-
- const typename graph_type::node_type& graph_node (
- unsigned long i
- ) const;
- /*!
- requires
- - drawable::m is locked
- - i < number_of_nodes()
- ensures
- - returns a const reference to get_graph().node(i)
- !*/
-
- typename graph_type::node_type& graph_node (
- unsigned long i
- );
- /*!
- requires
- - drawable::m is locked
- - i < number_of_nodes()
- ensures
- - returns a non-const reference to get_graph().node(i)
- !*/
-
- void save_graph (
- std::ostream& out
- );
- /*!
- ensures
- - saves the state of the graph to the output stream. Does so in a
- way that not only preserves the state of the graph this->graph()
- but also preserves the graphical layout of the graph in this
- GUI widget.
- - Also, the first part of the saved state is a serialized
- version of this->graph(). Thus, you can deserialize just the
- this->graph() object from the serialized data if you like.
- !*/
-
- void load_graph (
- std::istream& in
- );
- /*!
- ensures
- - loads a saved graph from the given input stream.
- !*/
-
- void set_node_label (unsigned long i, const std::wstring& label);
- void set_node_label (unsigned long i, const dlib::ustring& label);
- void set_node_label (
- unsigned long i,
- const std::string& label
- );
- /*!
- requires
- - i < number_of_nodes()
- ensures
- - #node_label(i) == label
- !*/
-
- void set_node_color (
- unsigned long i,
- rgb_pixel color
- );
- /*!
- requires
- - i < number_of_nodes()
- ensures
- - #node_color(i) == color
- !*/
-
- rgb_pixel node_color (
- unsigned long i
- ) const;
- /*!
- requires
- - i < number_of_nodes()
- ensures
- - returns the color used to draw node graph_node(i)
- !*/
-
- const std::wstring node_wlabel (unsigned long i) const;
- const dlib::ustring node_ulabel (unsigned long i) const;
- const std::string node_label (
- unsigned long i
- ) const;
- /*!
- requires
- - i < number_of_nodes()
- ensures
- - returns the text label for node graph_node(i)
- !*/
-
- template <
- typename T
- >
- void set_node_selected_handler (
- T& object,
- void (T::*event_handler)(unsigned long node_index)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the user selects
- a node.
- - node_index == the index of the node that was selected
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_node_selected_handler (
- const any_function<void(unsigned long node_index)>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the user selects
- a node.
- - node_index == the index of the node that was selected
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_node_deselected_handler (
- T& object,
- void (T::*event_handler)(unsigned long node_index)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the user
- deselects a node.
- - node_index == the index of the node that was deselected
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_node_deselected_handler (
- const any_function<void(unsigned long node_index)>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the user deselects a node.
- - node_index == the index of the node that was deselected
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_node_deleted_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the user
- deletes a node.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_node_deleted_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the user deletes a node.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- template <
- typename T
- >
- void set_graph_modified_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the user
- modifies the graph (i.e. adds or removes a node or edge)
- - the event_handler function is not called when the user just
- moves nodes around on the screen.
- - This event is always dispatched before any more specific event
- that results from the user modifying the graph.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_graph_modified_handler (
- const any_function<void()>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the user modifies
- the graph (i.e. adds or removes a node or edge)
- - the event_handler function is not called when the user just
- moves nodes around on the screen.
- - This event is always dispatched before any more specific event
- that results from the user modifying the graph.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- directed_graph_drawer(directed_graph_drawer&); // copy constructor
- directed_graph_drawer& operator=(directed_graph_drawer&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class text_grid : public scrollable_region
- {
- /*!
- INITIAL VALUE
- - vertical_scroll_increment() == 10
- - horizontal_scroll_increment() == 10
- - border_color() == rgb_pixel(128,128,128)
- - number_of_columns() == 0
- - number_of_rows() == 0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple grid of square text fields that
- looks more or less like a spreadsheet grid.
- !*/
-
- public:
-
- text_grid (
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- throws
- - std::bad_alloc
- - dlib::thread_error
- !*/
-
- virtual ~text_grid (
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_grid_size (
- unsigned long rows,
- unsigned long cols
- );
- /*!
- ensures
- - #number_of_rows() == rows
- - #number_of_columns() == cols
- - for all valid r and c:
- - #text(r,c) == ""
- - #text_color(r,c) == rgb_pixel(0,0,0)
- - #background_color(r,c) == rgb_pixel(255,255,255)
- - #is_editable(r,c) == true
- !*/
-
- unsigned long number_of_columns (
- ) const;
- /*!
- ensures
- - returns the number of columns contained in this grid
- !*/
-
- unsigned long number_of_rows (
- ) const;
- /*!
- ensures
- - returns the number of rows contained in this grid
- !*/
-
- rgb_pixel border_color (
- ) const;
- /*!
- ensures
- - returns the color of the lines drawn between the grid elements
- !*/
-
- void set_border_color (
- rgb_pixel color
- );
- /*!
- ensures
- - #border_color() == color
- !*/
-
- const std::wstring wtext (unsigned long row, unsigned long col) const;
- const dlib::ustring utext (unsigned long row, unsigned long col) const;
- const std::string text (
- unsigned long row,
- unsigned long col
- ) const;
- /*!
- requires
- - row < number_of_rows()
- - col < number_of_columns()
- ensures
- - returns the text in the given grid location
- !*/
-
- void set_text (unsigned long row, unsigned long col, const std::wstring& str);
- void set_text (unsigned long row, unsigned long col, const dlib::ustring& str);
- void set_text (
- unsigned long row,
- unsigned long col,
- const std::string& str
- );
- /*!
- requires
- - row < number_of_rows()
- - col < number_of_columns()
- ensures
- - #text(row,col) == str
- !*/
-
- const rgb_pixel text_color (
- unsigned long row,
- unsigned long col
- ) const;
- /*!
- requires
- - row < number_of_rows()
- - col < number_of_columns()
- ensures
- - returns the color of the text in the given grid location
- !*/
-
- void set_text_color (
- unsigned long row,
- unsigned long col,
- const rgb_pixel color
- );
- /*!
- requires
- - row < number_of_rows()
- - col < number_of_columns()
- ensures
- - #text_color(row,col) == color
- !*/
-
- const rgb_pixel background_color (
- unsigned long row,
- unsigned long col
- ) const;
- /*!
- requires
- - row < number_of_rows()
- - col < number_of_columns()
- ensures
- - returns the background color of the given grid location
- !*/
-
- void set_background_color (
- unsigned long row,
- unsigned long col,
- const rgb_pixel color
- );
- /*!
- requires
- - row < number_of_rows()
- - col < number_of_columns()
- ensures
- - #background_color(row,col) == color
- !*/
-
- bool is_editable (
- unsigned long row,
- unsigned long col
- ) const;
- /*!
- requires
- - row < number_of_rows()
- - col < number_of_columns()
- ensures
- - if (the given grid location is editable by the user) then
- - returns true
- - else
- - returns false
- !*/
-
- void set_editable (
- unsigned long row,
- unsigned long col,
- bool editable
- );
- /*!
- requires
- - row < number_of_rows()
- - col < number_of_columns()
- ensures
- - #is_editable(row,col) == editable
- !*/
-
- void set_column_width (
- unsigned long col,
- unsigned long width
- );
- /*!
- requires
- - col < number_of_columns()
- ensures
- - the given column will be displayed such that it is width pixels wide
- !*/
-
- void set_row_height (
- unsigned long row,
- unsigned long height
- );
- /*!
- requires
- - row < number_of_rows()
- ensures
- - the given row will be displayed such that it is height pixels wide
- !*/
-
- template <
- typename T
- >
- void set_text_modified_handler (
- T& object,
- void (T::*event_handler)(unsigned long row, unsigned long col)
- );
- /*!
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the user selects
- a node.
- - row == row will give the row of the grid item that was modified
- - col == col will give the column of the grid item that was modified
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- void set_text_modified_handler (
- const any_function<void(unsigned long row, unsigned long col)>& event_handler
- );
- /*!
- ensures
- - the event_handler function is called when the user selects a node.
- - row == row will give the row of the grid item that was modified
- - col == col will give the column of the grid item that was modified
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- !*/
-
- private:
-
- // restricted functions
- text_grid(text_grid&); // copy constructor
- text_grid& operator=(text_grid&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class image_display : public scrollable_region
- {
- /*!
- INITIAL VALUE
- - This object isn't displaying anything.
- - get_overlay_rects().size() == 0
- - get_default_overlay_rect_label() == ""
- - get_default_overlay_rect_color() == rgb_alpha_pixel(255,0,0,255) (i.e. RED)
- - This object does not have any user labelable parts defined.
- - overlay_editing_is_enabled() == true
-
- WHAT THIS OBJECT REPRESENTS
- This object represents an image inside a scrollable region.
- You give it an image to display by calling set_image().
- This widget also allows you to add rectangle and line overlays that
- will be drawn on top of the image.
-
- If you hold the Ctrl key you can zoom in and out using the mouse wheel.
- You can also add new overlay rectangles by holding shift, left clicking,
- and dragging the mouse. Additionally, you can delete an overlay rectangle
- by double clicking on it and hitting delete or backspace. Finally, you
- can also add part labels (if they have been defined by calling add_labelable_part_name())
- by selecting an overlay rectangle with the mouse and then right clicking
- on the part. If you want to move any rectangle or an object part then
- shift+right click and drag it.
-
- Finally, if you hold Ctrl and left click an overlay rectangle it will
- change its label to get_default_overlay_rect_label() and color to
- get_default_overlay_rect_color().
-
- The image is drawn such that:
- - the pixel img[0][0] is the upper left corner of the image.
- - the pixel img[img.nr()-1][0] is the lower left corner of the image.
- - the pixel img[0][img.nc()-1] is the upper right corner of the image.
- - the pixel img[img.nr()-1][img.nc()-1] is the lower right corner of the image.
- !*/
-
- public:
-
- image_display(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- !*/
-
- ~image_display(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- template <
- typename image_type
- >
- void set_image (
- const image_type& new_img
- );
- /*!
- requires
- - image_type == an implementation of array2d/array2d_kernel_abstract.h or
- a dlib::matrix or something convertible to a matrix via mat()
- - pixel_traits<typename image_type::type> must be defined
- ensures
- - #*this widget is now displaying the given image new_img.
- !*/
-
- struct overlay_rect
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a rectangle that is drawn on top of the
- image shown by this object. Each rectangle is represented by
- a rectangle object as well as a color and text label. The label
- is drawn below the lower right corner of the rectangle.
-
- Moreover, the rectangle can have sub-parts. Each part is listed
- in the parts member variable. This variable maps the name of the
- part to its position.
-
- Rectangles with crossed_out == true will be drawn with an X through
- them.
- !*/
-
- rectangle rect;
- rgb_alpha_pixel color;
- std::string label;
- std::map<std::string,point> parts;
- bool crossed_out;
-
- overlay_rect(
- );
- /*!
- ensures
- - #color == rgb_alpha_pixel(0,0,0,0)
- - #rect == rectangle()
- - #label.size() == 0
- - #crossed_out == false
- !*/
-
- template <typename pixel_type>
- overlay_rect(
- const rectangle& r,
- pixel_type p
- );
- /*!
- ensures
- - #rect == r
- - performs assign_pixel(color, p)
- - #label.size() == 0
- - #crossed_out == false
- !*/
-
- template <typename pixel_type>
- overlay_rect(
- const rectangle& r,
- pixel_type p,
- const std::string& l
- );
- /*!
- ensures
- - #rect == r
- - performs assign_pixel(color, p)
- - #label == l
- - #crossed_out == false
- !*/
-
- template <typename pixel_type>
- overlay_rect(
- const rectangle& r,
- pixel_type p,
- const std::string& l,
- const std::map<std::string,point>& parts_
- );
- /*!
- ensures
- - #rect == r
- - performs assign_pixel(color, p)
- - #label == l
- - #parts == parts_
- - #crossed_out == false
- !*/
-
- };
-
- struct overlay_line
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a line that is drawn on top of the
- image shown by this object. Each line is represented by
- its two end points (p1 and p2) as well as a color.
- !*/
-
- point p1;
- point p2;
- rgb_alpha_pixel color;
-
- overlay_line(
- );
- /*!
- ensures
- - #color == rgb_alpha_pixel(0,0,0,0)
- - #p1 == point()
- - #p2 == point()
- !*/
-
- template <typename pixel_type>
- overlay_line(
- const point& p1_,
- const point& p2_,
- pixel_type p
- );
- /*!
- ensures
- - performs assign_pixel(color, p)
- - #p1 == p1_
- - #p2 == p2_
- !*/
-
- };
-
- struct overlay_circle
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a circle that is drawn on top of the
- image shown by this object. Each circle is represented by
- its center, radius, and color. It can also have an optional
- text label which will appear below the circle.
- !*/
-
- point center;
- int radius;
- rgb_alpha_pixel color;
- std::string label;
-
- overlay_circle(
- );
- /*!
- ensures
- - #center == point(0,0)
- - #radius == 0
- - #color == rgb_alpha_pixel(0,0,0,0)
- - #label.size() == 0
- !*/
-
- template <typename pixel_type>
- overlay_circle(
- const point& center_,
- const int radius_,
- pixel_type p
- );
- /*!
- ensures
- - performs assign_pixel(color, p)
- - #center == center_
- - #radius == radius_
- !*/
-
- template <typename pixel_type>
- overlay_circle(
- const point& center_,
- const int radius_,
- pixel_type p,
- const std::string& label_
- );
- /*!
- ensures
- - performs assign_pixel(color, p)
- - #center == center_
- - #radius == radius_
- - #label == label_
- !*/
-
- };
-
- void add_overlay (
- const overlay_rect& overlay
- );
- /*!
- ensures
- - adds the given overlay rectangle into this object such
- that it will be displayed.
- !*/
-
- void add_overlay (
- const overlay_line& overlay
- );
- /*!
- ensures
- - adds the given overlay line into this object such
- that it will be displayed.
- !*/
-
- void add_overlay (
- const overlay_circle& overlay
- );
- /*!
- ensures
- - adds the given overlay circle into this object such
- that it will be displayed.
- !*/
-
- void add_overlay (
- const std::vector<overlay_rect>& overlay
- );
- /*!
- ensures
- - adds the given set of overlay rectangles into this object such
- that they will be displayed.
- !*/
-
- void add_overlay (
- const std::vector<overlay_line>& overlay
- );
- /*!
- ensures
- - adds the given set of overlay lines into this object such
- that they will be displayed.
- !*/
-
- void add_overlay (
- const std::vector<overlay_circle>& overlay
- );
- /*!
- ensures
- - adds the given set of overlay circles into this object such
- that they will be displayed.
- !*/
-
- void clear_overlay (
- );
- /*!
- ensures
- - removes all overlays from this object.
- - #get_overlay_rects().size() == 0
- !*/
-
- std::vector<overlay_rect> get_overlay_rects (
- ) const;
- /*!
- ensures
- - returns a copy of all the overlay_rect objects currently displayed.
- !*/
-
- void set_default_overlay_rect_label (
- const std::string& label
- );
- /*!
- ensures
- - #get_default_overlay_rect_label() == label
- !*/
-
- std::string get_default_overlay_rect_label (
- ) const;
- /*!
- ensures
- - returns the label given to new overlay rectangles created by the user
- (i.e. when the user holds shift and adds them with the mouse)
- !*/
-
- void set_default_overlay_rect_color (
- const rgb_alpha_pixel& color
- );
- /*!
- ensures
- - #get_default_overlay_rect_color() == color
- !*/
-
- rgb_alpha_pixel get_default_overlay_rect_color (
- ) const;
- /*!
- ensures
- - returns the color given to new overlay rectangles created by the user
- (i.e. when the user holds shift and adds them with the mouse)
- !*/
-
- void add_labelable_part_name (
- const std::string& name
- );
- /*!
- ensures
- - adds a user labelable part with the given name. If the name has
- already been added then this function has no effect.
- - These parts can be added by the user by selecting an overlay box
- and then right clicking anywhere in it. A popup menu will appear
- listing the parts. The user can then click a part name and it will
- add it into the overlay_rect::parts variable and also show it on the
- screen.
- !*/
-
- void clear_labelable_part_names (
- );
- /*!
- ensures
- - removes all use labelable parts. Calling this function undoes
- all previous calls to add_labelable_part_name(). Therefore, the
- user won't be able to label any parts after clear_labelable_part_names()
- is called.
- !*/
-
- rectangle get_image_display_rect (
- ) const;
- /*!
- ensures
- - returns a rectangle R that tells you how big the image inside the
- display is when it appears on the screen. Note that it takes the
- current zoom level into account.
- - R.width() == the width of the displayed image
- - R.height() == the height of the displayed image
- - R.tl_corner() == (0,0)
- !*/
-
- void enable_overlay_editing (
- );
- /*!
- ensures
- - #overlay_editing_is_enabled() == true
- !*/
-
- void disable_overlay_editing (
- );
- /*!
- ensures
- - #overlay_editing_is_enabled() == false
- !*/
-
- bool overlay_editing_is_enabled (
- ) const;
- /*!
- ensures
- - if this function returns true then it is possible for the user to add or
- remove overlay objects (e.g. rectangles) using the mouse and keyboard.
- If it returns false then the overlay is not user editable.
- !*/
-
- template <
- typename T
- >
- void set_overlay_rects_changed_handler (
- T& object,
- void (T::*event_handler)()
- );
- /*
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - the event_handler function is called on object when the user adds,
- removes, or modifies an overlay rectangle.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- */
-
- void set_overlay_rects_changed_handler (
- const any_function<void()>& event_handler
- );
- /*
- ensures
- - the event_handler function is called when the user adds or removes
- an overlay rectangle.
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- */
-
- template <
- typename T
- >
- void set_overlay_rect_selected_handler (
- T& object,
- void (T::*event_handler)(const overlay_rect& orect)
- );
- /*
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - The event_handler function is called on object when the user selects
- an overlay rectangle by double clicking on it. The selected rectangle
- will be passed to event_handler().
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- */
-
- void set_overlay_rect_selected_handler (
- const any_function<void(const overlay_rect& orect)>& event_handler
- );
- /*
- ensures
- - The event_handler function is called when the user selects an overlay
- rectangle by double clicking on it. The selected rectangle will be
- passed to event_handler().
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- */
-
- template <
- typename T
- >
- void set_image_clicked_handler (
- T& object,
- void (T::*event_handler)(const point& p, bool is_double_click, unsigned long btn)
- );
- /*
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - The event_handler function is called on object when the user left clicks
- anywhere on the image. When they do so this callback is called with the
- location of the image pixel which was clicked. The is_double_click bool
- will also tell you if it was a double click or single click.
- - btn == the button that was released. (either base_window::LEFT, base_window::MIDDLE, or base_window::RIGHT)
- - any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- throws
- - std::bad_alloc
- */
-
- void set_image_clicked_handler (
- const any_function<void(const point& p, bool is_double_click, unsigned long btn)>& event_handler
- );
- /*
- ensures
- - The event_handler function is called when the user left clicks anywhere
- on the image. When they do so this callback is called with the location
- of the image pixel which was clicked. The is_double_click bool will also
- tell you if it was a double click or single click.
- - btn == the button that was released. (either base_window::LEFT, base_window::MIDDLE, or base_window::RIGHT)
- - Any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this event at a
- time)
- throws
- - std::bad_alloc
- */
-
- private:
-
- // restricted functions
- image_display(image_display&); // copy constructor
- image_display& operator=(image_display&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class image_window : public drawable_window
- {
- /*!
- INITIAL VALUE
- - initially, this object is visible on the screen
- - events_tied() == false
-
- WHAT THIS OBJECT REPRESENTS
- This is a simple window that is just a container for an image_display.
- It exists to make it easy to throw image_displays onto the screen
- without having to put together your own drawable_window objects.
- !*/
- public:
-
- typedef image_display::overlay_rect overlay_rect;
- typedef image_display::overlay_line overlay_line;
- typedef image_display::overlay_circle overlay_circle;
-
- image_window(
- );
- /*!
- ensures
- - this object is properly initialized
- !*/
-
- template <typename image_type>
- image_window(
- const image_type& img
- );
- /*!
- requires
- - image_type == an implementation of array2d/array2d_kernel_abstract.h or
- a dlib::matrix or something convertible to a matrix via mat()
- - pixel_traits<typename image_type::type> must be defined
- ensures
- - this object is properly initialized
- - #*this window is now displaying the given image img.
- !*/
-
- template < typename image_type>
- image_window(
- const image_type& img,
- const std::string& title
- );
- /*!
- requires
- - image_type == an implementation of array2d/array2d_kernel_abstract.h or
- a dlib::matrix or something convertible to a matrix via mat()
- - pixel_traits<typename image_type::type> must be defined
- ensures
- - this object is properly initialized
- - #*this window is now displaying the given image img.
- - The title of the window will be set to the given title string.
- !*/
-
- ~image_window(
- );
- /*!
- ensures
- - any resources associated with this object have been released
- !*/
-
- template <typename image_type>
- void set_image (
- const image_type& img
- );
- /*!
- requires
- - image_type == an implementation of array2d/array2d_kernel_abstract.h
- - pixel_traits<typename image_type::type> must be defined
- ensures
- - #*this window is now displaying the given image img.
- !*/
-
- void add_overlay (
- const overlay_rect& overlay
- );
- /*!
- ensures
- - adds the given overlay rectangle into this object such
- that it will be displayed.
- !*/
-
- template <typename pixel_type>
- void add_overlay(
- const rectangle& r,
- pixel_type p = rgb_pixel(255,0,0)
- );
- /*!
- ensures
- - performs: add_overlay(overlay_rect(r,p));
- !*/
-
- template <typename pixel_type>
- void add_overlay(
- const rectangle& r,
- pixel_type p,
- const std::string& l
- );
- /*!
- ensures
- - performs: add_overlay(overlay_rect(r,p,l));
- !*/
-
- template <typename pixel_type>
- void add_overlay(
- const std::vector<rectangle>& r,
- pixel_type p = rgb_pixel(255,0,0)
- );
- /*!
- ensures
- - adds the given set of rectangles into this object such
- that they will be displayed with the color specific by p.
- !*/
-
- void add_overlay(
- const full_object_detection& object,
- const std::vector<std::string>& part_names
- );
- /*!
- ensures
- - adds the given full_object_detection to the overlays
- and shows it on the screen. This includes any of its
- parts that are not set equal to OBJECT_PART_NOT_PRESENT.
- - for all valid i < part_names.size():
- - the part object.part(i) will be labeled with the string
- part_names[i].
- !*/
-
- void add_overlay(
- const full_object_detection& object
- );
- /*!
- ensures
- - adds the given full_object_detection to the overlays
- and shows it on the screen. This includes any of its
- parts that are not set equal to OBJECT_PART_NOT_PRESENT.
- !*/
-
- void add_overlay(
- const std::vector<full_object_detection>& objects,
- const std::vector<std::string>& part_names
- );
- /*!
- ensures
- - calling this function is equivalent to calling the following
- sequence of functions, for all valid i:
- - add_overlay(objects[i], part_names);
- !*/
-
- void add_overlay(
- const std::vector<full_object_detection>& objects
- );
- /*!
- ensures
- - calling this function is equivalent to calling the following
- sequence of functions, for all valid i:
- - add_overlay(objects[i]);
- !*/
-
- void add_overlay (
- const overlay_line& overlay
- );
- /*!
- ensures
- - adds the given overlay line into this object such
- that it will be displayed.
- !*/
-
- void add_overlay (
- const overlay_circle& overlay
- );
- /*!
- ensures
- - adds the given overlay circle into this object such
- that it will be displayed.
- !*/
-
- template <typename pixel_type>
- void add_overlay(
- const point& p1,
- const point& p2,
- pixel_type p
- );
- /*!
- ensures
- - performs: add_overlay(overlay_line(p1,p2,p));
- !*/
-
- void add_overlay (
- const std::vector<overlay_rect>& overlay
- );
- /*!
- ensures
- - adds the given set of overlay rectangles into this object such
- that they will be displayed.
- !*/
-
- void add_overlay (
- const std::vector<overlay_line>& overlay
- );
- /*!
- ensures
- - adds the given set of overlay lines into this object such
- that they will be displayed.
- !*/
-
- void add_overlay (
- const std::vector<overlay_circle>& overlay
- );
- /*!
- ensures
- - adds the given set of overlay circles into this object such
- that they will be displayed.
- !*/
-
- void clear_overlay (
- );
- /*!
- ensures
- - removes all overlays from this object.
- !*/
-
- void tie_events (
- );
- /*!
- ensures
- - #events_tied() == true
- !*/
-
- void untie_events (
- );
- /*!
- ensures
- - #events_tied() == false
- !*/
-
- bool events_tied (
- ) const;
- /*!
- ensures
- - returns true if and only if the get_next_double_click() and
- get_next_keypress() events are tied together. If they are tied it means
- that you can use a loop of the following form to listen for both events
- simultaneously:
- while (mywindow.get_next_double_click(p) || mywindow.get_next_keypress(key,printable))
- {
- if (p.x() < 0)
- // Do something with the keyboard event
- else
- // Do something with the mouse event
- }
- !*/
-
- bool get_next_double_click (
- point& p
- );
- /*!
- ensures
- - This function blocks until the user double clicks on the image or the
- window is closed by the user. It will also unblock for a keyboard key
- press if events_tied() == true.
- - if (this function returns true) then
- - This means the user double clicked the mouse.
- - #p == the next image pixel the user clicked.
- - else
- - #p == point(-1,1)
- !*/
-
- bool get_next_double_click (
- point& p,
- unsigned long& mouse_button
- );
- /*!
- ensures
- - This function blocks until the user double clicks on the image or the
- window is closed by the user. It will also unblock for a keyboard key
- press if events_tied() == true.
- - if (this function returns true) then
- - This means the user double clicked the mouse.
- - #p == the next image pixel the user clicked.
- - #mouse_button == the mouse button which was used to double click.
- This will be either dlib::base_window::LEFT,
- dlib::base_window::MIDDLE, or dlib::base_window::RIGHT
- - else
- - #p == point(-1,1)
- (Note that this point is outside any possible image)
- !*/
-
- bool get_next_keypress (
- unsigned long& key,
- bool& is_printable,
- unsigned long& state
- );
- /*!
- ensures
- - This function blocks until the user presses a keyboard key or the
- window is closed by the user. It will also unblock for a mouse double
- click if events_tied() == true.
- - if (this function returns true) then
- - This means the user pressed a keyboard key.
- - The keyboard button press is recorded into #key, #is_printable, and
- #state. In particular, these variables are populated with the three
- identically named arguments to the base_window::on_keydown(key,is_printable,state)
- event.
- !*/
-
- bool get_next_keypress (
- unsigned long& key,
- bool& is_printable
- );
- /*!
- ensures
- - This function blocks until the user presses a keyboard key or the
- window is closed by the user. It will also unblock for a mouse double
- click if events_tied() == true.
- - This function is the equivalent to calling get_next_keypress(key,is_printable,temp)
- and then discarding temp.
- !*/
-
- private:
-
- // restricted functions
- image_window(image_window&);
- image_window& operator= (image_window&);
- };
-
-// ----------------------------------------------------------------------------------------
-
- class perspective_display : public drawable, noncopyable
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object is a tool for displaying 3D point clouds on a screen. You can
- navigate the display with the mouse. Left click and drag rotates the
- camera around the displayed data. Scrolling the mouse wheel zooms and
- shift+left click (or just right click) and drag pans the view around.
- !*/
-
- public:
-
- perspective_display(
- drawable_window& w
- );
- /*!
- ensures
- - #*this is properly initialized
- - #*this has been added to window w
- - #parent_window() == w
- !*/
-
- ~perspective_display(
- );
- /*!
- ensures
- - all resources associated with *this have been released
- !*/
-
- void set_size (
- unsigned long width,
- unsigned long height
- );
- /*!
- ensures
- - #width() == width
- - #height() == height
- - #top() == top()
- - #left() == left()
- - i.e. The location of the upper left corner of this widget stays the
- same but its width and height are modified.
- !*/
-
- struct overlay_line
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a line that is drawn on the screen. Each line
- is represented by its two end points (p1 and p2) as well as a color.
- !*/
-
- overlay_line() { assign_pixel(color, 0);}
-
- overlay_line(const vector<double>& p1_, const vector<double>& p2_)
- : p1(p1_), p2(p2_) { assign_pixel(color, 255); }
-
- template <typename pixel_type>
- overlay_line(const vector<double>& p1_, const vector<double>& p2_, pixel_type p)
- : p1(p1_), p2(p2_) { assign_pixel(color, p); }
-
- vector<double> p1;
- vector<double> p2;
- rgb_pixel color;
- };
-
- struct overlay_dot
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a dot that is drawn on the screen. Each dot is
- represented by one point and a color.
- !*/
-
- overlay_dot() { assign_pixel(color, 0);}
-
- overlay_dot(const vector<double>& p_)
- : p(p_) { assign_pixel(color, 255); }
-
- template <typename pixel_type>
- overlay_dot(const vector<double>& p_, pixel_type color_)
- : p(p_) { assign_pixel(color, color_); }
-
- vector<double> p; // The location of the dot
- rgb_pixel color;
- };
-
- void add_overlay (
- const std::vector<overlay_line>& overlay
- );
- /*!
- ensures
- - Adds the given overlay lines into this object such that it will be
- displayed.
- !*/
-
- void add_overlay (
- const std::vector<overlay_dot>& overlay
- );
- /*!
- ensures
- - Adds the given overlay dots into this object such that it will be
- displayed.
- !*/
-
- void clear_overlay (
- );
- /*!
- ensures
- - Removes all overlays from this object. The display will be empty.
- !*/
-
- template <typename T>
- void set_dot_double_clicked_handler (
- T& object,
- void (T::*event_handler)(const vector<double>&)
- );
- /*
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - The event_handler function is called on object when the user double
- clicks on one of the overlay dots. The selected dot will be passed to
- event_handler().
- - Any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- */
-
- void set_dot_double_clicked_handler (
- const any_function<void(const vector<double>&)>& event_handler
- );
- /*
- ensures
- - The event_handler function is called when the user double clicks on one
- of the overlay dots. The selected dot will be passed to event_handler().
- - Any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- */
- };
-
-// ----------------------------------------------------------------------------------------
-
- class perspective_window : public drawable_window, noncopyable
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is a simple window that is just a container for a perspective_display.
- It exists to make it easy to throw perspective_displays onto the screen
- without having to put together your own drawable_window objects.
- !*/
- public:
-
- typedef perspective_display::overlay_line overlay_line;
- typedef perspective_display::overlay_dot overlay_dot;
-
- perspective_window(
- );
- /*!
- ensures
- - The window is displayed on the screen and is 100x100 pixels in size.
- !*/
-
- perspective_window(
- const std::vector<dlib::vector<double> >& point_cloud
- );
- /*!
- ensures
- - The window is displayed on the screen and is 100x100 pixels in size.
- - This window will have point_cloud added to it via add_overlay() and the
- points will all be white.
- !*/
-
- perspective_window(
- const std::vector<dlib::vector<double> >& point_cloud,
- const std::string& title
- );
- /*!
- ensures
- - The window is displayed on the screen and is 100x100 pixels in size.
- - This window will have point_cloud added to it via add_overlay() and the
- points will all be white.
- - The title of the window will be set to the given title string.
- !*/
-
- ~perspective_window(
- );
- /*!
- ensures
- - any resources associated with this object have been released
- !*/
-
- void add_overlay (
- const std::vector<overlay_line>& overlay
- );
- /*!
- ensures
- - Adds the given overlay lines into this object such that it will be
- displayed.
- !*/
-
- void add_overlay (
- const std::vector<overlay_dot>& overlay
- );
- /*!
- ensures
- - Adds the given overlay dots into this object such that it will be
- displayed.
- !*/
-
- void clear_overlay (
- );
- /*!
- ensures
- - Removes all overlays from this object. The display will be empty.
- !*/
-
- void add_overlay(
- const std::vector<dlib::vector<double> >& d
- );
- /*!
- ensures
- - Adds the given dots into this object such that it will be
- displayed. They will be colored white.
- !*/
-
- template <typename pixel_type>
- void add_overlay(
- const std::vector<dlib::vector<double> >& d,
- pixel_type p
- );
- /*!
- ensures
- - Adds the given dots into this object such that it will be
- displayed. They will be colored by pixel color p.
- !*/
-
- template <typename pixel_type>
- void add_overlay(
- const vector<double>& p1,
- const vector<double>& p2,
- pixel_type color
- );
- /*!
- ensures
- - Adds an overlay line going from p1 to p2 with the given color.
- !*/
-
- template < typename T >
- void set_dot_double_clicked_handler (
- T& object,
- void (T::*event_handler)(const vector<double>&)
- );
- /*
- requires
- - event_handler is a valid pointer to a member function in T
- ensures
- - The event_handler function is called on object when the user double
- clicks on one of the overlay dots. The selected dot will be passed to
- event_handler().
- - Any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- */
-
- void set_dot_double_clicked_handler (
- const any_function<void(const vector<double>&)>& event_handler
- );
- /*
- ensures
- - The event_handler function is called when the user double clicks on one
- of the overlay dots. The selected dot will be passed to event_handler().
- - Any previous calls to this function are overridden by this new call.
- (i.e. you can only have one event handler associated with this
- event at a time)
- */
-
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_WIDGETs_ABSTRACT_
-