Commit 0a1069d0 authored by Davis King's avatar Davis King

Added the ability for the user to delete overlay rectangles from the image_display.

Also added interface functions to programmatically observe what is happening to the
overlays.
parent 1154cf73
......@@ -5661,12 +5661,13 @@ namespace dlib
image_display(
drawable_window& w
):
scrollable_region(w),
scrollable_region(w,KEYBOARD_EVENTS),
zoom_in_scale(1),
zoom_out_scale(1),
drawing_rect(true),
rect_is_selected(false),
selected_rect(0)
selected_rect(0),
default_rect_color(255,0,0,255)
{
enable_mouse_drag();
......@@ -5801,7 +5802,7 @@ namespace dlib
orect.bottom() = orect.bottom()*zoom_in_scale/zoom_out_scale;
if (rect_is_selected && selected_rect == i)
draw_rectangle(c, translate_rect(orect, origin), rgb_pixel(0,255,0), area);
draw_rectangle(c, translate_rect(orect, origin), invert_pixel(overlay_rects[i].color), area);
else
draw_rectangle(c, translate_rect(orect, origin), overlay_rects[i].color, area);
......@@ -5826,7 +5827,30 @@ namespace dlib
}
if (drawing_rect)
draw_rectangle(c, rect_to_draw, rgb_pixel(0,255,255), area);
draw_rectangle(c, rect_to_draw, invert_pixel(default_rect_color), area);
}
// ----------------------------------------------------------------------------------------
void image_display::
on_keydown (
unsigned long key,
bool is_printable,
unsigned long state
)
{
scrollable_region::on_keydown(key,is_printable, state);
if (!is_printable && !hidden && enabled && rect_is_selected &&
(key == base_window::KEY_BACKSPACE || key == base_window::KEY_DELETE))
{
rect_is_selected = false;
overlay_rects.erase(overlay_rects.begin() + selected_rect);
parent.invalidate_rectangle(rect);
if (event_handler.is_set())
event_handler();
}
}
// ----------------------------------------------------------------------------------------
......@@ -5845,7 +5869,7 @@ namespace dlib
if (rect.contains(x,y) == false || hidden || !enabled)
return;
if (!is_double_click && btn == base_window::LEFT && (state&base_window::CONTROL))
if (!is_double_click && btn == base_window::LEFT && (state&base_window::SHIFT))
{
drawing_rect = true;
rect_anchor = point(x,y);
......@@ -5894,7 +5918,7 @@ namespace dlib
}
if (best_dist < 10)
if (best_dist < 13)
{
rect_is_selected = true;
selected_rect = best_idx;
......@@ -5910,6 +5934,58 @@ namespace dlib
}
}
// ----------------------------------------------------------------------------------------
std::vector<image_display::overlay_rect> image_display::
get_overlay_rects (
) const
{
auto_mutex lock(m);
return overlay_rects;
}
// ----------------------------------------------------------------------------------------
void image_display::
set_default_overlay_rect_label (
const std::string& label
)
{
auto_mutex lock(m);
default_rect_label = label;
}
// ----------------------------------------------------------------------------------------
std::string image_display::
get_default_overlay_rect_label (
) const
{
auto_mutex lock(m);
return default_rect_label;
}
// ----------------------------------------------------------------------------------------
void image_display::
set_default_overlay_rect_color (
const rgb_alpha_pixel& color
)
{
auto_mutex lock(m);
default_rect_color = color;
}
// ----------------------------------------------------------------------------------------
rgb_alpha_pixel image_display::
get_default_overlay_rect_color (
) const
{
auto_mutex lock(m);
return default_rect_color;
}
// ----------------------------------------------------------------------------------------
void image_display::
......@@ -5922,7 +5998,7 @@ namespace dlib
{
scrollable_region::on_mouse_up(btn,state,x,y);
if (drawing_rect && btn == base_window::LEFT && (state&base_window::CONTROL) &&
if (drawing_rect && btn == base_window::LEFT && (state&base_window::SHIFT) &&
!hidden && enabled)
{
const point origin(total_rect().tl_corner());
......@@ -5943,7 +6019,12 @@ namespace dlib
const rectangle new_rect(c1,c2);
if (new_rect.width() > 0 && new_rect.height() > 0)
add_overlay(overlay_rect(new_rect, rgb_pixel(255,0,0)));
{
add_overlay(overlay_rect(new_rect, default_rect_color, default_rect_label));
if (event_handler.is_set())
event_handler();
}
}
if (drawing_rect)
......@@ -5966,7 +6047,7 @@ namespace dlib
if (drawing_rect)
{
if ((state&base_window::LEFT) && (state&base_window::CONTROL) && !hidden && enabled)
if ((state&base_window::LEFT) && (state&base_window::SHIFT) && !hidden && enabled)
{
rectangle new_rect(point(x,y), rect_anchor);
parent.invalidate_rectangle(new_rect + rect_to_draw);
......
......@@ -3304,6 +3304,44 @@ namespace dlib
void clear_overlay (
);
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_;
}
private:
void draw (
......@@ -3339,6 +3377,15 @@ namespace dlib
long y
);
void on_keydown (
unsigned long key,
bool is_printable,
unsigned long state
);
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); }
array2d<rgb_alpha_pixel> img;
......@@ -3352,6 +3399,9 @@ namespace dlib
rectangle rect_to_draw;
bool rect_is_selected;
unsigned long selected_rect;
rgb_alpha_pixel default_rect_color;
std::string default_rect_label;
any_function<void()> event_handler;
// restricted functions
image_display(image_display&); // copy constructor
......
......@@ -2317,14 +2317,22 @@ namespace dlib
{
/*!
INITIAL VALUE
This object isn't displaying anything.
- This object isn't displaying anything.
- get_overlay_rects().size() == 0
- get_default_overlay_rect_label() == ""
- get_default_overlay_rect_color() == rgb_alpha_pixel(255,0,0,255) (i.e. RED)
WHAT THIS OBJECT REPRESENTS
This object represents an image inside a scrollable region.
You give it an image to display by calling set_image().
This widget also allows you to add rectangle and line overlays that
will be drawn on top of the image. Finally, if you hold the Ctrl key
you can zoom in and out using the mouse wheel.
will be drawn on top of the image.
If you hold the Ctrl key you can zoom in and out using the mouse wheel.
You can also add new overlay rectangles by holding shift, left clicking,
and dragging the mouse. Finally, you can delete an overlay rectangle
by double clicking on it and hitting delete or backspace.
The image is drawn such that:
- the pixel img[0][0] is the upper left corner of the image.
......@@ -2495,8 +2503,82 @@ namespace dlib
/*!
ensures
- removes all overlays from this object.
- #get_overlay_rects().size() == 0
!*/
std::vector<overlay_rect> get_overlay_rects (
) const;
/*!
ensures
- returns a copy of all the overlay_rect objects currently displayed.
!*/
void set_default_overlay_rect_label (
const std::string& label
);
/*!
ensures
- #get_default_overlay_rect_label() == label
!*/
std::string get_default_overlay_rect_label (
) const;
/*!
ensures
- returns the label given to new overlay rectangles created by the user
(i.e. when the user holds shift and adds them with the mouse)
!*/
void set_default_overlay_rect_color (
const rgb_alpha_pixel& color
);
/*!
ensures
- #get_default_overlay_rect_color() == color
!*/
rgb_alpha_pixel get_default_overlay_rect_color (
) const;
/*!
ensures
- returns the color given to new overlay rectangles created by the user
(i.e. when the user holds shift and adds them with the mouse)
!*/
template <
typename T
>
void set_overlay_rects_changed_handler (
T& object,
void (T::*event_handler_)()
);
/*
requires
- event_handler is a valid pointer to a member function in T
ensures
- the event_handler function is called on object when the user adds
or removes an overlay rectangle.
- any previous calls to this function are overridden by this new call.
(i.e. you can only have one event handler associated with this
event at a time)
throws
- std::bad_alloc
*/
void set_overlay_rects_changed_handler (
const any_function<void()>& event_handler
);
/*
ensures
- the event_handler function is called when the user adds or removes
an overlay rectangle.
- any previous calls to this function are overridden by this new call.
(i.e. you can only have one event handler associated with this
event at a time)
throws
- std::bad_alloc
*/
private:
// restricted functions
......
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