summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/gui_widgets/widgets.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/gui_widgets/widgets.h')
-rw-r--r--ml/dlib/dlib/gui_widgets/widgets.h4165
1 files changed, 0 insertions, 4165 deletions
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_
-