Commit e079088e authored by Davis King's avatar Davis King

Added support for user drawn rectangle overlays and selectable overlays to the

image_display widget.
parent 0af9abde
......@@ -5663,7 +5663,10 @@ namespace dlib
):
scrollable_region(w),
zoom_in_scale(1),
zoom_out_scale(1)
zoom_out_scale(1),
drawing_rect(true),
rect_is_selected(false),
selected_rect(0)
{
enable_mouse_drag();
......@@ -5797,7 +5800,11 @@ namespace dlib
orect.top() = orect.top()*zoom_in_scale/zoom_out_scale;
orect.bottom() = orect.bottom()*zoom_in_scale/zoom_out_scale;
draw_rectangle(c, translate_rect(orect, origin), overlay_rects[i].color, area);
if (rect_is_selected && selected_rect == i)
draw_rectangle(c, translate_rect(orect, origin), rgb_pixel(0,255,0), area);
else
draw_rectangle(c, translate_rect(orect, origin), overlay_rects[i].color, area);
if (overlay_rects[i].label.size() != 0)
{
// make a rectangle that is at the spot we want to draw our string
......@@ -5817,6 +5824,160 @@ namespace dlib
zoom_in_scale*overlay_lines[i].p2/zoom_out_scale + origin,
overlay_lines[i].color, area);
}
if (drawing_rect)
draw_rectangle(c, rect_to_draw, rgb_pixel(0,255,255), area);
}
// ----------------------------------------------------------------------------------------
void image_display::
on_mouse_down (
unsigned long btn,
unsigned long state,
long x,
long y,
bool is_double_click
)
{
scrollable_region::on_mouse_down(btn, state, x, y, is_double_click);
if (rect.contains(x,y) == false || hidden || !enabled)
return;
if (!is_double_click && btn == base_window::LEFT && (state&base_window::CONTROL))
{
drawing_rect = true;
rect_anchor = point(x,y);
if (rect_is_selected)
{
rect_is_selected = false;
parent.invalidate_rectangle(rect);
}
}
else if (drawing_rect)
{
if (rect_is_selected)
rect_is_selected = false;
drawing_rect = false;
parent.invalidate_rectangle(rect);
}
else if (is_double_click)
{
const point origin(total_rect().tl_corner());
const bool rect_was_selected = rect_is_selected;
rect_is_selected = false;
long best_dist = std::numeric_limits<long>::max();
long best_idx = 0;
// check if this click landed on any of the overlay rectangles
for (unsigned long i = 0; i < overlay_rects.size(); ++i)
{
rectangle orect = overlay_rects[i].rect;
orect.left() = orect.left()*zoom_in_scale/zoom_out_scale;
orect.right() = orect.right()*zoom_in_scale/zoom_out_scale;
orect.top() = orect.top()*zoom_in_scale/zoom_out_scale;
orect.bottom() = orect.bottom()*zoom_in_scale/zoom_out_scale;
orect = translate_rect(orect, origin);
const long dist = distance_to_rect_edge(orect, point(x,y));
if (dist < best_dist)
{
best_dist = dist;
best_idx = i;
}
}
if (best_dist < 10)
{
rect_is_selected = true;
selected_rect = best_idx;
}
if (rect_is_selected || rect_was_selected)
parent.invalidate_rectangle(rect);
}
else if (rect_is_selected)
{
rect_is_selected = false;
parent.invalidate_rectangle(rect);
}
}
// ----------------------------------------------------------------------------------------
void image_display::
on_mouse_up (
unsigned long btn,
unsigned long state,
long x,
long y
)
{
scrollable_region::on_mouse_up(btn,state,x,y);
if (drawing_rect && btn == base_window::LEFT && (state&base_window::CONTROL) &&
!hidden && enabled)
{
const point origin(total_rect().tl_corner());
point c1 = point(x,y) - origin;
point c2 = rect_anchor - origin;
if (zoom_in_scale != 1)
{
c1 = c1/(double)zoom_in_scale;
c2 = c2/(double)zoom_in_scale;
}
else if (zoom_out_scale != 1)
{
c1 = c1*(double)zoom_out_scale;
c2 = c2*(double)zoom_out_scale;
}
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)));
}
if (drawing_rect)
{
drawing_rect = false;
parent.invalidate_rectangle(rect);
}
}
// ----------------------------------------------------------------------------------------
void image_display::
on_mouse_move (
unsigned long state,
long x,
long y
)
{
scrollable_region::on_mouse_move(state,x,y);
if (drawing_rect)
{
if ((state&base_window::LEFT) && (state&base_window::CONTROL) && !hidden && enabled)
{
rectangle new_rect(point(x,y), rect_anchor);
parent.invalidate_rectangle(new_rect + rect_to_draw);
rect_to_draw = new_rect;
}
else
{
drawing_rect = false;
parent.invalidate_rectangle(rect);
}
}
}
// ----------------------------------------------------------------------------------------
......@@ -5826,6 +5987,10 @@ namespace dlib
unsigned long state
)
{
// disable mouse wheel if the user is drawing a rectangle
if (drawing_rect)
return;
// if CONTROL is not being held down
if ((state & base_window::CONTROL) == 0)
{
......@@ -5876,6 +6041,10 @@ namespace dlib
unsigned long state
)
{
// disable mouse wheel if the user is drawing a rectangle
if (drawing_rect)
return;
// if CONTROL is not being held down
if ((state & base_window::CONTROL) == 0)
{
......
......@@ -3200,11 +3200,24 @@ namespace dlib
- 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.
!*/
public:
......@@ -3305,6 +3318,27 @@ namespace dlib
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
);
array2d<rgb_alpha_pixel> img;
......@@ -3313,6 +3347,11 @@ namespace dlib
long zoom_in_scale;
long zoom_out_scale;
bool drawing_rect;
point rect_anchor;
rectangle rect_to_draw;
bool rect_is_selected;
unsigned long selected_rect;
// restricted functions
image_display(image_display&); // copy constructor
......
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