Commit 958a21a0 authored by Davis King's avatar Davis King

Now you can move overlay rectangles and their parts around on the image_display

by holding shift and right clicking and dragging.
parent 0209f51a
......@@ -6374,6 +6374,7 @@ namespace dlib
if (!is_printable && !hidden && enabled && rect_is_selected &&
(key == base_window::KEY_BACKSPACE || key == base_window::KEY_DELETE))
{
moving_overlay = false;
rect_is_selected = false;
parts_menu.disable();
if (selected_part_name.size() == 0)
......@@ -6456,6 +6457,89 @@ namespace dlib
if (!overlay_editing_enabled)
return;
if (btn == base_window::RIGHT && (state&base_window::SHIFT))
{
const bool rect_was_selected = rect_is_selected;
rect_is_selected = false;
parts_menu.disable();
long best_dist = std::numeric_limits<long>::max();
long best_idx = 0;
std::string best_part;
// check if this click landed on any of the overlay rectangles
for (unsigned long i = 0; i < overlay_rects.size(); ++i)
{
const rectangle orect = get_rect_on_screen(i);
const long dist = distance_to_rect_edge(orect, point(x,y));
if (dist < best_dist)
{
best_dist = dist;
best_idx = i;
best_part.clear();
}
std::map<std::string,point>::const_iterator itr;
for (itr = overlay_rects[i].parts.begin(); itr != overlay_rects[i].parts.end(); ++itr)
{
rectangle temp = centered_rect(get_rect_on_screen(centered_rect(itr->second,1,1)), part_width, part_width);
point c = center(temp);
// distance from edge of part circle
const long dist = static_cast<long>(std::abs(length(c - point(x,y)) + 0.5 - temp.width()/2));
if (dist < best_dist)
{
best_idx = i;
best_dist = dist;
best_part = itr->first;
}
}
}
if (best_dist < 13)
{
moving_overlay = true;
moving_rect = best_idx;
moving_part_name = best_part;
// If we are moving one of the sides of the rectangle rather than one of
// the parts circles then we need to figure out which side of the rectangle
// we are moving.
if (best_part.size() == 0)
{
// which side is the click closest to?
const rectangle orect = get_rect_on_screen(best_idx);
const point p = nearest_point(orect,point(x,y));
long dist_left = std::abs(p.x()-orect.left());
long dist_top = std::abs(p.y()-orect.top());
long dist_right = std::abs(p.x()-orect.right());
long dist_bottom = std::abs(p.y()-orect.bottom());
long min_val = std::min(std::min(dist_left,dist_right),std::min(dist_top,dist_bottom));
if (dist_left == min_val)
moving_what = MOVING_RECT_LEFT;
else if (dist_top == min_val)
moving_what = MOVING_RECT_TOP;
else if (dist_right == min_val)
moving_what = MOVING_RECT_RIGHT;
else
moving_what = MOVING_RECT_BOTTOM;
}
else
{
moving_what = MOVING_PART;
}
// Do this to make the moving stuff snap to the mouse immediately.
on_mouse_move(state|btn,x,y);
}
if (rect_was_selected)
parent.invalidate_rectangle(rect);
return;
}
if (btn == base_window::RIGHT && rect_is_selected)
{
last_right_click_pos = point(x,y);
......@@ -6687,6 +6771,10 @@ namespace dlib
drawing_rect = false;
parent.invalidate_rectangle(rect);
}
if (moving_overlay)
{
moving_overlay = false;
}
}
// ----------------------------------------------------------------------------------------
......@@ -6713,6 +6801,61 @@ namespace dlib
drawing_rect = false;
parent.invalidate_rectangle(rect);
}
moving_overlay = false;
}
else if (moving_overlay)
{
if ((state&base_window::RIGHT) && (state&base_window::SHIFT) && !hidden && enabled)
{
// map point(x,y) into the image coordinate space.
point p = point(x,y) - total_rect().tl_corner();
if (zoom_in_scale != 1)
{
if (moving_what == MOVING_PART)
p = p/(double)zoom_in_scale-dpoint(0.5,0.5);
else
p = p/(double)zoom_in_scale;
}
else if (zoom_out_scale != 1)
{
p = p*(double)zoom_out_scale;
}
if (moving_what == MOVING_PART)
{
if (overlay_rects[moving_rect].parts[moving_part_name] != p)
{
overlay_rects[moving_rect].parts[moving_part_name] = p;
parent.invalidate_rectangle(rect);
if (event_handler.is_set())
event_handler();
}
}
else
{
rectangle original = overlay_rects[moving_rect].rect;
if (moving_what == MOVING_RECT_LEFT)
overlay_rects[moving_rect].rect.left() = std::min(p.x(), overlay_rects[moving_rect].rect.right());
else if (moving_what == MOVING_RECT_RIGHT)
overlay_rects[moving_rect].rect.right() = std::max(p.x()-1, overlay_rects[moving_rect].rect.left());
else if (moving_what == MOVING_RECT_TOP)
overlay_rects[moving_rect].rect.top() = std::min(p.y(), overlay_rects[moving_rect].rect.bottom());
else
overlay_rects[moving_rect].rect.bottom() = std::max(p.y()-1, overlay_rects[moving_rect].rect.top());
if (original != overlay_rects[moving_rect].rect)
{
parent.invalidate_rectangle(rect);
if (event_handler.is_set())
event_handler();
}
}
}
else
{
moving_overlay = false;
}
}
}
......
......@@ -3231,6 +3231,16 @@ namespace dlib
- 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:
......@@ -3581,6 +3591,17 @@ namespace dlib
timer<image_display> highlight_timer;
unsigned long highlighted_rect;
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
......
......@@ -2338,7 +2338,8 @@ namespace dlib
by double clicking on it and hitting delete or backspace. Finally, you
can also add part labels (if they have been defined by calling add_labelable_part_name())
by selecting an overlay rectangle with the mouse and then right clicking
on the part.
on the part. If you want to move any rectangle or an object part then
shift+right click and drag it.
Finally, if you hold Ctrl and left click an overlay rectangle it will
change its label to get_default_overlay_rect_label().
......
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