Commit 098a1ce9 authored by Davis King's avatar Davis King

Added copy and paste support to the text_field and also cleaned up some

of the popup_menu stuff.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402730
parent ce6e08e3
...@@ -1707,7 +1707,7 @@ namespace dlib ...@@ -1707,7 +1707,7 @@ namespace dlib
for (unsigned long i = 0; i < items.size(); ++i) for (unsigned long i = 0; i < items.size(); ++i)
{ {
if (std::tolower(key) == std::tolower(items[i]->get_hot_key()) && if (std::tolower(key) == std::tolower(items[i]->get_hot_key()) &&
(items[i]->has_click_event() || submenus[i]) ) (items[i]->has_click_event() || submenus[i]) && item_enabled[i] )
{ {
// only hide this popup window if this isn't a submenu // only hide this popup window if this isn't a submenu
if (submenus[i] == 0) if (submenus[i] == 0)
...@@ -3078,6 +3078,8 @@ namespace dlib ...@@ -3078,6 +3078,8 @@ namespace dlib
drawable(w,MOUSE_CLICK | KEYBOARD_EVENTS | FOCUS_EVENTS | WINDOW_MOVED), drawable(w,MOUSE_CLICK | KEYBOARD_EVENTS | FOCUS_EVENTS | WINDOW_MOVED),
popup_menu_shown(false) popup_menu_shown(false)
{ {
menu_.set_on_hide_handler(*this,&popup_menu_region::on_menu_becomes_hidden);
enable_events(); enable_events();
} }
...@@ -3102,6 +3104,17 @@ namespace dlib ...@@ -3102,6 +3104,17 @@ namespace dlib
rect = resize_rect(rect,width,height); 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:: popup_menu& popup_menu_region::
...@@ -3153,6 +3166,21 @@ namespace dlib ...@@ -3153,6 +3166,21 @@ namespace dlib
menu_.hide(); menu_.hide();
popup_menu_shown = false; 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;
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -1676,19 +1676,17 @@ namespace dlib ...@@ -1676,19 +1676,17 @@ namespace dlib
if (c.intersect(rect).is_empty()) if (c.intersect(rect).is_empty())
return; return;
if (enabled) unsigned char color = 0;
{
f->draw_string(c,rect,text); if (enabled == false)
} color = 128;
else
{ f->draw_string(c,rect,text,color);
f->draw_string(c,rect,text,128);
}
if (underline_p1 != underline_p2) if (underline_p1 != underline_p2)
{ {
point base(rect.left(),rect.top()); point base(rect.left(),rect.top());
draw_line(c, base+underline_p1, base+underline_p2); draw_line(c, base+underline_p1, base+underline_p2, color);
} }
} }
...@@ -2486,6 +2484,10 @@ namespace dlib ...@@ -2486,6 +2484,10 @@ namespace dlib
class popup_menu_region : public drawable class popup_menu_region : public drawable
{ {
/*!
CONVENTION
popup_menu_visible() == popup_menu_shown
!*/
public: public:
...@@ -2501,6 +2503,10 @@ namespace dlib ...@@ -2501,6 +2503,10 @@ namespace dlib
long height long height
); );
void set_rect (
const rectangle& new_rect
);
popup_menu& menu ( popup_menu& menu (
); );
...@@ -2510,6 +2516,9 @@ namespace dlib ...@@ -2510,6 +2516,9 @@ namespace dlib
void disable ( void disable (
); );
bool popup_menu_visible (
) const { auto_mutex M(m); return popup_menu_shown; }
protected: protected:
void on_keydown ( void on_keydown (
...@@ -2535,6 +2544,9 @@ namespace dlib ...@@ -2535,6 +2544,9 @@ namespace dlib
bool is_double_click bool is_double_click
); );
void on_menu_becomes_hidden (
);
void draw ( void draw (
const canvas& const canvas&
) const; ) const;
......
...@@ -1481,6 +1481,9 @@ namespace dlib ...@@ -1481,6 +1481,9 @@ namespace dlib
class popup_menu_region : public drawable class popup_menu_region : public drawable
{ {
/*! /*!
INITIAL VALUE
- popup_menu_visible() == false
WHAT THIS OBJECT REPRESENTS WHAT THIS OBJECT REPRESENTS
This object represents a region on a window where if the user This object represents a region on a window where if the user
right clicks the mouse over this region a popup_menu pops up. right clicks the mouse over this region a popup_menu pops up.
...@@ -1525,6 +1528,24 @@ namespace dlib ...@@ -1525,6 +1528,24 @@ namespace dlib
same but its width and height are modified 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 ( popup_menu& menu (
); );
/*! /*!
......
...@@ -431,6 +431,140 @@ namespace dlib ...@@ -431,6 +431,140 @@ namespace dlib
return text_rect; return text_rect;
} }
// ----------------------------------------------------------------------------------------
void text_field::
enable (
)
{
drawable::enable();
right_click_menu.enable();
}
// ----------------------------------------------------------------------------------------
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 (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:: void text_field::
...@@ -442,6 +576,7 @@ namespace dlib ...@@ -442,6 +576,7 @@ namespace dlib
t.stop(); t.stop();
has_focus = false; has_focus = false;
cursor_visible = false; cursor_visible = false;
right_click_menu.disable();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -470,6 +605,7 @@ namespace dlib ...@@ -470,6 +605,7 @@ namespace dlib
// font size // font size
rect.set_bottom(rect.top() + mfont->height()+ (style->get_padding(*mfont))*2); rect.set_bottom(rect.top() + mfont->height()+ (style->get_padding(*mfont))*2);
set_text(text_); set_text(text_);
right_click_menu.set_rect(get_text_rect());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -563,16 +699,28 @@ namespace dlib ...@@ -563,16 +699,28 @@ namespace dlib
unsigned long width unsigned long width
) )
{ {
auto_mutex M(m);
if (width < style->get_padding(*mfont)*2) if (width < style->get_padding(*mfont)*2)
return; return;
m.lock();
rectangle old(rect); rectangle old(rect);
rect.set_right(rect.left() + width - 1); rect.set_right(rect.left() + width - 1);
right_click_menu.set_rect(get_text_rect());
parent.invalidate_rectangle(rect+old); parent.invalidate_rectangle(rect+old);
m.unlock(); }
// ----------------------------------------------------------------------------------------
void text_field::
set_pos (
long x,
long y
)
{
drawable::set_pos(x,y);
right_click_menu.set_rect(get_text_rect());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -716,6 +864,7 @@ namespace dlib ...@@ -716,6 +864,7 @@ namespace dlib
move_cursor(l+1); move_cursor(l+1);
highlight_start = f; highlight_start = f;
highlight_end = l; highlight_end = l;
on_text_is_selected();
} }
else else
{ {
...@@ -751,6 +900,7 @@ namespace dlib ...@@ -751,6 +900,7 @@ namespace dlib
{ {
highlight_start = 0; highlight_start = 0;
highlight_end = -1; highlight_end = -1;
on_no_text_selected();
parent.invalidate_rectangle(rect); parent.invalidate_rectangle(rect);
} }
} }
...@@ -764,6 +914,7 @@ namespace dlib ...@@ -764,6 +914,7 @@ namespace dlib
shift_pos = -1; shift_pos = -1;
highlight_start = 0; highlight_start = 0;
highlight_end = -1; highlight_end = -1;
on_no_text_selected();
if (focus_lost_handler.is_set()) if (focus_lost_handler.is_set())
focus_lost_handler(); focus_lost_handler();
...@@ -780,6 +931,11 @@ namespace dlib ...@@ -780,6 +931,11 @@ namespace dlib
unsigned long state 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 ustring space_str = convert_utf8_to_utf32(std::string(" \t\n"));
const bool shift = (state&base_window::KBD_MOD_SHIFT) != 0; const bool shift = (state&base_window::KBD_MOD_SHIFT) != 0;
const bool ctrl = (state&base_window::KBD_MOD_CONTROL) != 0; const bool ctrl = (state&base_window::KBD_MOD_CONTROL) != 0;
...@@ -841,6 +997,7 @@ namespace dlib ...@@ -841,6 +997,7 @@ namespace dlib
{ {
highlight_start = 0; highlight_start = 0;
highlight_end = -1; highlight_end = -1;
on_no_text_selected();
parent.invalidate_rectangle(rect); parent.invalidate_rectangle(rect);
} }
...@@ -879,6 +1036,7 @@ namespace dlib ...@@ -879,6 +1036,7 @@ namespace dlib
{ {
highlight_start = 0; highlight_start = 0;
highlight_end = -1; highlight_end = -1;
on_no_text_selected();
parent.invalidate_rectangle(rect); parent.invalidate_rectangle(rect);
} }
} }
...@@ -888,10 +1046,19 @@ namespace dlib ...@@ -888,10 +1046,19 @@ namespace dlib
{ {
if (key == 'a') if (key == 'a')
{ {
move_cursor(static_cast<long>(text_.size())); on_select_all();
highlight_start = 0; }
highlight_end = static_cast<long>(text_.size()-1); else if (key == 'c')
parent.invalidate_rectangle(rect); {
on_copy();
}
else if (key == 'v')
{
on_paste();
}
else if (key == 'x')
{
on_cut();
} }
} }
else if (key != '\n') else if (key != '\n')
...@@ -903,6 +1070,7 @@ namespace dlib ...@@ -903,6 +1070,7 @@ namespace dlib
move_cursor(highlight_start+1); move_cursor(highlight_start+1);
highlight_start = 0; highlight_start = 0;
highlight_end = -1; highlight_end = -1;
on_no_text_selected();
parent.invalidate_rectangle(rect); parent.invalidate_rectangle(rect);
} }
else else
...@@ -929,14 +1097,7 @@ namespace dlib ...@@ -929,14 +1097,7 @@ namespace dlib
// if something is highlighted then delete that // if something is highlighted then delete that
if (highlight_start <= highlight_end) if (highlight_start <= highlight_end)
{ {
text_ = text_.erase(highlight_start,highlight_end-highlight_start+1); on_delete_selected();
move_cursor(highlight_start);
highlight_start = 0;
highlight_end = -1;
// send out the text modified event
if (text_modified_handler.is_set())
text_modified_handler();
} }
else if (cursor_pos != 0) else if (cursor_pos != 0)
{ {
...@@ -961,14 +1122,7 @@ namespace dlib ...@@ -961,14 +1122,7 @@ namespace dlib
// if something is highlighted then delete that // if something is highlighted then delete that
if (highlight_start <= highlight_end) if (highlight_start <= highlight_end)
{ {
text_ = text_.erase(highlight_start,highlight_end-highlight_start+1); on_delete_selected();
move_cursor(highlight_start);
highlight_start = 0;
highlight_end = -1;
// send out the text modified event
if (text_modified_handler.is_set())
text_modified_handler();
} }
else if (cursor_pos != static_cast<long>(text_.size())) else if (cursor_pos != static_cast<long>(text_.size()))
{ {
...@@ -995,6 +1149,7 @@ namespace dlib ...@@ -995,6 +1149,7 @@ namespace dlib
{ {
highlight_start = 0; highlight_start = 0;
highlight_end = -1; highlight_end = -1;
on_no_text_selected();
parent.invalidate_rectangle(rect); parent.invalidate_rectangle(rect);
} }
} }
...@@ -1005,6 +1160,7 @@ namespace dlib ...@@ -1005,6 +1160,7 @@ namespace dlib
{ {
highlight_start = 0; highlight_start = 0;
highlight_end = -1; highlight_end = -1;
on_no_text_selected();
parent.invalidate_rectangle(rect); parent.invalidate_rectangle(rect);
} }
} }
...@@ -1030,6 +1186,7 @@ namespace dlib ...@@ -1030,6 +1186,7 @@ namespace dlib
move_cursor(highlight_start+ustr.size()); move_cursor(highlight_start+ustr.size());
highlight_start = 0; highlight_start = 0;
highlight_end = -1; highlight_end = -1;
on_no_text_selected();
parent.invalidate_rectangle(rect); parent.invalidate_rectangle(rect);
} }
else else
...@@ -1119,6 +1276,11 @@ namespace dlib ...@@ -1119,6 +1276,11 @@ namespace dlib
highlight_end = -1; highlight_end = -1;
} }
if (highlight_start > highlight_end)
on_no_text_selected();
else
on_text_is_selected();
recent_movement = true; recent_movement = true;
cursor_visible = true; cursor_visible = true;
parent.invalidate_rectangle(rect); parent.invalidate_rectangle(rect);
......
...@@ -359,12 +359,22 @@ namespace dlib ...@@ -359,12 +359,22 @@ namespace dlib
highlight_start(0), highlight_start(0),
highlight_end(-1), highlight_end(-1),
shift_pos(-1), shift_pos(-1),
t(*this,&text_field::timer_action) t(*this,&text_field::timer_action),
right_click_menu(w)
{ {
style.reset(new text_field_style_default()); style.reset(new text_field_style_default());
rect.set_bottom(mfont->height()+ (style->get_padding(*mfont))*2); rect.set_bottom(mfont->height()+ (style->get_padding(*mfont))*2);
rect.set_right((style->get_padding(*mfont))*2); rect.set_right((style->get_padding(*mfont))*2);
cursor_x = style->get_padding(*mfont); 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(); enable_events();
t.set_delay_time(500); t.set_delay_time(500);
...@@ -430,6 +440,11 @@ namespace dlib ...@@ -430,6 +440,11 @@ namespace dlib
unsigned long width unsigned long width
); );
void set_pos (
long x,
long y
);
void set_main_font ( void set_main_font (
const shared_ptr_thread_safe<font>& f const shared_ptr_thread_safe<font>& f
); );
...@@ -443,9 +458,15 @@ namespace dlib ...@@ -443,9 +458,15 @@ namespace dlib
void disable ( void disable (
); );
void enable (
);
void hide ( void hide (
); );
void show (
);
template < template <
typename T typename T
> >
...@@ -485,6 +506,27 @@ namespace dlib ...@@ -485,6 +506,27 @@ namespace dlib
private: 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 ( void on_user_event (
int num int num
) )
...@@ -561,6 +603,8 @@ namespace dlib ...@@ -561,6 +603,8 @@ namespace dlib
timer<text_field>::kernel_2a t; timer<text_field>::kernel_2a t;
popup_menu_region right_click_menu;
// restricted functions // restricted functions
text_field(text_field&); // copy constructor text_field(text_field&); // copy constructor
text_field& operator=(text_field&); // assignment operator text_field& operator=(text_field&); // assignment operator
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment