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