Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
ac4666cb
Commit
ac4666cb
authored
Mar 22, 2015
by
Davis King
Browse files
Added the perspective_display and perspective_window GUI tools.
parent
3ff14401
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
799 additions
and
0 deletions
+799
-0
dlib/gui_widgets/widgets.cpp
dlib/gui_widgets/widgets.cpp
+300
-0
dlib/gui_widgets/widgets.h
dlib/gui_widgets/widgets.h
+229
-0
dlib/gui_widgets/widgets_abstract.h
dlib/gui_widgets/widgets_abstract.h
+270
-0
No files found.
dlib/gui_widgets/widgets.cpp
View file @
ac4666cb
...
...
@@ -5652,6 +5652,306 @@ namespace dlib
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// perspective_display member functions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
perspective_display
::
perspective_display
(
drawable_window
&
w
)
:
drawable
(
w
,
MOUSE_MOVE
|
MOUSE_CLICK
|
MOUSE_WHEEL
)
{
clear_overlay
();
enable_events
();
}
// ----------------------------------------------------------------------------------------
perspective_display
::
~
perspective_display
(
)
{
disable_events
();
parent
.
invalidate_rectangle
(
rect
);
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
set_size
(
unsigned
long
width
,
unsigned
long
height
)
{
auto_mutex
lock
(
m
);
rectangle
old
(
rect
);
rect
=
resize_rect
(
rect
,
width
,
height
);
tform
=
camera_transform
(
tform
.
get_camera_pos
(),
tform
.
get_camera_looking_at
(),
tform
.
get_camera_up_direction
(),
tform
.
get_camera_field_of_view
(),
std
::
min
(
rect
.
width
(),
rect
.
height
()));
parent
.
invalidate_rectangle
(
old
+
rect
);
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
add_overlay
(
const
std
::
vector
<
overlay_line
>&
overlay
)
{
auto_mutex
M
(
m
);
if
(
overlay
.
size
()
==
0
)
return
;
// push this new overlay into our overlay vector
overlay_lines
.
insert
(
overlay_lines
.
end
(),
overlay
.
begin
(),
overlay
.
end
());
for
(
unsigned
long
i
=
0
;
i
<
overlay
.
size
();
++
i
)
{
sum_pts
+=
overlay
[
i
].
p1
;
sum_pts
+=
overlay
[
i
].
p2
;
max_pts
.
x
()
=
std
::
max
(
overlay
[
i
].
p1
.
x
(),
max_pts
.
x
());
max_pts
.
x
()
=
std
::
max
(
overlay
[
i
].
p2
.
x
(),
max_pts
.
x
());
max_pts
.
y
()
=
std
::
max
(
overlay
[
i
].
p1
.
y
(),
max_pts
.
y
());
max_pts
.
y
()
=
std
::
max
(
overlay
[
i
].
p2
.
y
(),
max_pts
.
y
());
max_pts
.
z
()
=
std
::
max
(
overlay
[
i
].
p1
.
z
(),
max_pts
.
z
());
max_pts
.
z
()
=
std
::
max
(
overlay
[
i
].
p2
.
z
(),
max_pts
.
z
());
}
tform
=
camera_transform
(
max_pts
,
sum_pts
/
(
overlay_lines
.
size
()
*
2
+
overlay_dots
.
size
()),
vector
<
double
>
(
0
,
0
,
1
),
tform
.
get_camera_field_of_view
(),
std
::
min
(
rect
.
width
(),
rect
.
height
()));
// make the parent window redraw us now that we changed the overlay
parent
.
invalidate_rectangle
(
rect
);
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
add_overlay
(
const
std
::
vector
<
overlay_dot
>&
overlay
)
{
auto_mutex
M
(
m
);
if
(
overlay
.
size
()
==
0
)
return
;
// push this new overlay into our overlay vector
overlay_dots
.
insert
(
overlay_dots
.
end
(),
overlay
.
begin
(),
overlay
.
end
());
for
(
unsigned
long
i
=
0
;
i
<
overlay
.
size
();
++
i
)
{
sum_pts
+=
overlay
[
i
].
p
;
max_pts
.
x
()
=
std
::
max
(
overlay
[
i
].
p
.
x
(),
max_pts
.
x
());
max_pts
.
y
()
=
std
::
max
(
overlay
[
i
].
p
.
y
(),
max_pts
.
y
());
max_pts
.
z
()
=
std
::
max
(
overlay
[
i
].
p
.
z
(),
max_pts
.
z
());
}
tform
=
camera_transform
(
max_pts
,
sum_pts
/
(
overlay_lines
.
size
()
*
2
+
overlay_dots
.
size
()),
vector
<
double
>
(
0
,
0
,
1
),
tform
.
get_camera_field_of_view
(),
std
::
min
(
rect
.
width
(),
rect
.
height
()));
// make the parent window redraw us now that we changed the overlay
parent
.
invalidate_rectangle
(
rect
);
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
clear_overlay
(
)
{
auto_mutex
lock
(
m
);
overlay_dots
.
clear
();
overlay_lines
.
clear
();
sum_pts
=
vector
<
double
>
();
max_pts
=
vector
<
double
>
(
-
std
::
numeric_limits
<
double
>::
infinity
(),
-
std
::
numeric_limits
<
double
>::
infinity
(),
-
std
::
numeric_limits
<
double
>::
infinity
());
parent
.
invalidate_rectangle
(
rect
);
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
set_dot_double_clicked_handler
(
const
any_function
<
void
(
const
vector
<
double
>&
)
>&
event_handler_
)
{
auto_mutex
M
(
m
);
dot_clicked_event_handler
=
event_handler_
;
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
draw
(
const
canvas
&
c
)
const
{
rectangle
area
=
rect
.
intersect
(
c
);
fill_rect
(
c
,
area
,
0
);
for
(
unsigned
long
i
=
0
;
i
<
overlay_dots
.
size
();
++
i
)
{
point
p
=
tform
(
overlay_dots
[
i
].
p
)
+
rect
.
tl_corner
();
if
(
area
.
contains
(
p
))
assign_pixel
(
c
[
p
.
y
()
-
c
.
top
()][
p
.
x
()
-
c
.
left
()],
overlay_dots
[
i
].
color
);
}
for
(
unsigned
long
i
=
0
;
i
<
overlay_lines
.
size
();
++
i
)
{
draw_line
(
c
,
tform
(
overlay_lines
[
i
].
p1
),
tform
(
overlay_lines
[
i
].
p2
),
overlay_lines
[
i
].
color
,
area
);
}
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
on_wheel_up
(
unsigned
long
state
)
{
if
(
rect
.
contains
(
lastx
,
lasty
)
==
false
||
hidden
||
!
enabled
)
return
;
const
double
alpha
=
0.10
;
const
vector
<
double
>
delta
=
alpha
*
(
tform
.
get_camera_pos
()
-
tform
.
get_camera_looking_at
());
tform
=
camera_transform
(
tform
.
get_camera_pos
()
-
delta
,
tform
.
get_camera_looking_at
(),
tform
.
get_camera_up_direction
(),
tform
.
get_camera_field_of_view
(),
std
::
min
(
rect
.
width
(),
rect
.
height
()));
parent
.
invalidate_rectangle
(
rect
);
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
on_wheel_down
(
unsigned
long
state
)
{
if
(
rect
.
contains
(
lastx
,
lasty
)
==
false
||
hidden
||
!
enabled
)
return
;
const
double
alpha
=
0.10
;
const
vector
<
double
>
delta
=
alpha
*
(
tform
.
get_camera_pos
()
-
tform
.
get_camera_looking_at
());
tform
=
camera_transform
(
tform
.
get_camera_pos
()
+
delta
,
tform
.
get_camera_looking_at
(),
tform
.
get_camera_up_direction
(),
tform
.
get_camera_field_of_view
(),
std
::
min
(
rect
.
width
(),
rect
.
height
()));
parent
.
invalidate_rectangle
(
rect
);
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
on_mouse_down
(
unsigned
long
btn
,
unsigned
long
state
,
long
x
,
long
y
,
bool
is_double_click
)
{
if
(
btn
==
base_window
::
LEFT
||
btn
==
base_window
::
RIGHT
)
{
last
=
point
(
x
,
y
);
}
if
(
is_double_click
&&
btn
==
base_window
::
LEFT
&&
enabled
&&
!
hidden
&&
overlay_dots
.
size
()
!=
0
)
{
double
best_dist
=
std
::
numeric_limits
<
double
>::
infinity
();
unsigned
long
best_idx
=
0
;
const
dpoint
pp
(
x
,
y
);
for
(
unsigned
long
i
=
0
;
i
<
overlay_dots
.
size
();
++
i
)
{
dpoint
p
=
tform
(
overlay_dots
[
i
].
p
)
+
rect
.
tl_corner
();
double
dist
=
length_squared
(
p
-
pp
);
if
(
dist
<
best_dist
)
{
best_dist
=
dist
;
best_idx
=
i
;
}
}
if
(
dot_clicked_event_handler
.
is_set
())
dot_clicked_event_handler
(
overlay_dots
[
best_idx
].
p
);
}
}
// ----------------------------------------------------------------------------------------
void
perspective_display
::
on_mouse_move
(
unsigned
long
state
,
long
x
,
long
y
)
{
if
(
!
enabled
||
hidden
)
return
;
if
(
state
==
base_window
::
LEFT
)
{
const
point
cur
(
x
,
y
);
dpoint
delta
=
last
-
cur
;
last
=
cur
;
const
vector
<
double
>
radius
=
tform
.
get_camera_pos
()
-
tform
.
get_camera_looking_at
();
delta
*=
2
*
pi
*
length
(
radius
)
/
600.0
;
vector
<
double
>
tangent_x
=
tform
.
get_camera_up_direction
().
cross
(
radius
).
normalize
();
vector
<
double
>
tangent_y
=
radius
.
cross
(
tangent_x
).
normalize
();
vector
<
double
>
new_pos
=
tform
.
get_camera_pos
()
+
tangent_x
*
delta
.
x
()
+
tangent_y
*-
delta
.
y
();
// now make it have the correct radius relative to the looking at point.
new_pos
=
(
new_pos
-
tform
.
get_camera_looking_at
()).
normalize
()
*
length
(
radius
)
+
tform
.
get_camera_looking_at
();
tform
=
camera_transform
(
new_pos
,
tform
.
get_camera_looking_at
(),
tangent_y
,
tform
.
get_camera_field_of_view
(),
std
::
min
(
rect
.
width
(),
rect
.
height
()));
parent
.
invalidate_rectangle
(
rect
);
}
else
if
(
state
==
(
base_window
::
LEFT
|
base_window
::
SHIFT
)
||
state
==
base_window
::
RIGHT
)
{
const
point
cur
(
x
,
y
);
dpoint
delta
=
last
-
cur
;
last
=
cur
;
const
vector
<
double
>
radius
=
tform
.
get_camera_pos
()
-
tform
.
get_camera_looking_at
();
delta
*=
2
*
pi
*
length
(
radius
)
/
600.0
;
vector
<
double
>
tangent_x
=
tform
.
get_camera_up_direction
().
cross
(
radius
).
normalize
();
vector
<
double
>
tangent_y
=
radius
.
cross
(
tangent_x
).
normalize
();
vector
<
double
>
offset
=
tangent_x
*
delta
.
x
()
+
tangent_y
*-
delta
.
y
();
tform
=
camera_transform
(
tform
.
get_camera_pos
()
+
offset
,
tform
.
get_camera_looking_at
()
+
offset
,
tform
.
get_camera_up_direction
(),
tform
.
get_camera_field_of_view
(),
std
::
min
(
rect
.
width
(),
rect
.
height
()));
parent
.
invalidate_rectangle
(
rect
);
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// image_display member functions
...
...
dlib/gui_widgets/widgets.h
View file @
ac4666cb
...
...
@@ -3586,6 +3586,235 @@ namespace dlib
image_display
&
operator
=
(
image_display
&
);
// assignment operator
};
// ----------------------------------------------------------------------------------------
class
perspective_display
:
public
drawable
,
noncopyable
{
public:
perspective_display
(
drawable_window
&
w
);
~
perspective_display
(
);
virtual
void
set_size
(
unsigned
long
width
,
unsigned
long
height
);
struct
overlay_line
{
overlay_line
()
{
assign_pixel
(
color
,
0
);}
overlay_line
(
const
vector
<
double
>&
p1_
,
const
vector
<
double
>&
p2_
)
:
p1
(
p1_
),
p2
(
p2_
)
{
assign_pixel
(
color
,
255
);
}
template
<
typename
pixel_type
>
overlay_line
(
const
vector
<
double
>&
p1_
,
const
vector
<
double
>&
p2_
,
pixel_type
p
)
:
p1
(
p1_
),
p2
(
p2_
)
{
assign_pixel
(
color
,
p
);
}
vector
<
double
>
p1
;
vector
<
double
>
p2
;
rgb_pixel
color
;
};
struct
overlay_dot
{
overlay_dot
()
{
assign_pixel
(
color
,
0
);}
overlay_dot
(
const
vector
<
double
>&
p_
)
:
p
(
p_
)
{
assign_pixel
(
color
,
255
);
}
template
<
typename
pixel_type
>
overlay_dot
(
const
vector
<
double
>&
p_
,
pixel_type
color_
)
:
p
(
p_
)
{
assign_pixel
(
color
,
color_
);
}
vector
<
double
>
p
;
rgb_pixel
color
;
};
void
add_overlay
(
const
std
::
vector
<
overlay_line
>&
overlay
);
void
add_overlay
(
const
std
::
vector
<
overlay_dot
>&
overlay
);
void
clear_overlay
(
);
template
<
typename
T
>
void
set_dot_double_clicked_handler
(
T
&
object
,
void
(
T
::*
event_handler_
)(
const
vector
<
double
>&
)
)
{
auto_mutex
M
(
m
);
dot_clicked_event_handler
=
make_mfp
(
object
,
event_handler_
);
}
void
set_dot_double_clicked_handler
(
const
any_function
<
void
(
const
vector
<
double
>&
)
>&
event_handler_
);
private:
void
draw
(
const
canvas
&
c
)
const
;
void
on_wheel_up
(
unsigned
long
state
);
void
on_wheel_down
(
unsigned
long
state
);
void
on_mouse_down
(
unsigned
long
btn
,
unsigned
long
state
,
long
x
,
long
y
,
bool
is_double_click
);
void
on_mouse_move
(
unsigned
long
state
,
long
x
,
long
y
);
point
last
;
std
::
vector
<
overlay_line
>
overlay_lines
;
std
::
vector
<
overlay_dot
>
overlay_dots
;
camera_transform
tform
;
vector
<
double
>
sum_pts
;
vector
<
double
>
max_pts
;
any_function
<
void
(
const
vector
<
double
>&
)
>
dot_clicked_event_handler
;
};
// ----------------------------------------------------------------------------------------
class
perspective_window
:
public
drawable_window
,
noncopyable
{
public:
typedef
perspective_display
::
overlay_line
overlay_line
;
typedef
perspective_display
::
overlay_dot
overlay_dot
;
perspective_window
(
)
:
disp
(
*
this
)
{
set_size
(
100
,
100
);
}
perspective_window
(
const
std
::
vector
<
dlib
::
vector
<
double
>
>&
point_cloud
)
:
disp
(
*
this
)
{
set_size
(
100
,
100
);
add_overlay
(
point_cloud
);
show
();
}
perspective_window
(
const
std
::
vector
<
dlib
::
vector
<
double
>
>&
point_cloud
,
const
std
::
string
&
title
)
:
disp
(
*
this
)
{
set_size
(
100
,
100
);
add_overlay
(
point_cloud
);
set_title
(
title
);
show
();
}
~
perspective_window
(
)
{
// You should always call close_window() in the destructor of window
// objects to ensure that no events will be sent to this window while
// it is being destructed.
close_window
();
}
void
add_overlay
(
const
std
::
vector
<
overlay_line
>&
overlay
)
{
disp
.
add_overlay
(
overlay
);
}
void
add_overlay
(
const
std
::
vector
<
overlay_dot
>&
overlay
)
{
disp
.
add_overlay
(
overlay
);
}
void
clear_overlay
(
)
{
disp
.
clear_overlay
();
}
void
add_overlay
(
const
std
::
vector
<
dlib
::
vector
<
double
>
>&
d
)
{
add_overlay
(
d
,
255
);
}
template
<
typename
pixel_type
>
void
add_overlay
(
const
std
::
vector
<
dlib
::
vector
<
double
>
>&
d
,
pixel_type
p
)
{
std
::
vector
<
overlay_dot
>
temp
;
temp
.
resize
(
d
.
size
());
for
(
unsigned
long
i
=
0
;
i
<
temp
.
size
();
++
i
)
temp
[
i
]
=
overlay_dot
(
d
[
i
],
p
);
add_overlay
(
temp
);
}
template
<
typename
T
>
void
set_dot_double_clicked_handler
(
T
&
object
,
void
(
T
::*
event_handler_
)(
const
vector
<
double
>&
)
)
{
disp
.
set_dot_double_clicked_handler
(
object
,
event_handler_
);
}
void
set_dot_double_clicked_handler
(
const
any_function
<
void
(
const
vector
<
double
>&
)
>&
event_handler_
)
{
disp
.
set_dot_double_clicked_handler
(
event_handler_
);
}
private:
void
on_window_resized
(
)
{
drawable_window
::
on_window_resized
();
unsigned
long
width
,
height
;
get_size
(
width
,
height
);
disp
.
set_size
(
width
,
height
);
}
perspective_display
disp
;
};
// ----------------------------------------------------------------------------------------
class
image_window
:
public
drawable_window
...
...
dlib/gui_widgets/widgets_abstract.h
View file @
ac4666cb
...
...
@@ -3158,6 +3158,276 @@ namespace dlib
image_window
&
operator
=
(
image_window
&
);
};
// ----------------------------------------------------------------------------------------
class
perspective_display
:
public
drawable
,
noncopyable
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a tool for displaying 3D point clouds on a screen. You can
navigate the display with the mouse. Left click and drag rotates the
camera around the displayed data. Scrolling the mouse wheel zooms and
shift+left click (or just right click) and drag pans the view around.
!*/
public:
perspective_display
(
drawable_window
&
w
);
/*!
ensures
- #*this is properly initialized
- #*this has been added to window w
- #parent_window() == w
!*/
~
perspective_display
(
);
/*!
ensures
- all resources associated with *this have been released
!*/
void
set_size
(
unsigned
long
width
,
unsigned
long
height
);
/*!
ensures
- #width() == width
- #height() == height
- #top() == top()
- #left() == left()
- i.e. The location of the upper left corner of this widget stays the
same but its width and height are modified.
!*/
struct
overlay_line
{
/*!
WHAT THIS OBJECT REPRESENTS
This object represents a line that is drawn on the screen. Each line
is represented by its two end points (p1 and p2) as well as a color.
!*/
overlay_line
()
{
assign_pixel
(
color
,
0
);}
overlay_line
(
const
vector
<
double
>&
p1_
,
const
vector
<
double
>&
p2_
)
:
p1
(
p1_
),
p2
(
p2_
)
{
assign_pixel
(
color
,
255
);
}
template
<
typename
pixel_type
>
overlay_line
(
const
vector
<
double
>&
p1_
,
const
vector
<
double
>&
p2_
,
pixel_type
p
)
:
p1
(
p1_
),
p2
(
p2_
)
{
assign_pixel
(
color
,
p
);
}
vector
<
double
>
p1
;
vector
<
double
>
p2
;
rgb_pixel
color
;
};
struct
overlay_dot
{
/*!
WHAT THIS OBJECT REPRESENTS
This object represents a dot that is drawn on the screen. Each dot is
represented by one point and a color.
!*/
overlay_dot
()
{
assign_pixel
(
color
,
0
);}
overlay_dot
(
const
vector
<
double
>&
p_
)
:
p
(
p_
)
{
assign_pixel
(
color
,
255
);
}
template
<
typename
pixel_type
>
overlay_dot
(
const
vector
<
double
>&
p_
,
pixel_type
color_
)
:
p
(
p_
)
{
assign_pixel
(
color
,
color_
);
}
vector
<
double
>
p
;
// The location of the dot
rgb_pixel
color
;
};
void
add_overlay
(
const
std
::
vector
<
overlay_line
>&
overlay
);
/*!
ensures
- Adds the given overlay lines into this object such that it will be
displayed.
!*/
void
add_overlay
(
const
std
::
vector
<
overlay_dot
>&
overlay
);
/*!
ensures
- Adds the given overlay dots into this object such that it will be
displayed.
!*/
void
clear_overlay
(
);
/*!
ensures
- Removes all overlays from this object. The display will be empty.
!*/
template
<
typename
T
>
void
set_dot_double_clicked_handler
(
T
&
object
,
void
(
T
::*
event_handler
)(
const
vector
<
double
>&
)
);
/*
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 double
clicks on one of the overlay dots. The selected dot will be passed to
event_handler().
- 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)
*/
void
set_dot_double_clicked_handler
(
const
any_function
<
void
(
const
vector
<
double
>&
)
>&
event_handler
);
/*
ensures
- The event_handler function is called when the user double clicks on one
of the overlay dots. The selected dot will be passed to event_handler().
- 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)
*/
};
// ----------------------------------------------------------------------------------------
class
perspective_window
:
public
drawable_window
,
noncopyable
{
/*!
WHAT THIS OBJECT REPRESENTS
This is a simple window that is just a container for a perspective_display.
It exists to make it easy to throw perspective_displays onto the screen
without having to put together your own drawable_window objects.
!*/
public:
typedef
perspective_display
::
overlay_line
overlay_line
;
typedef
perspective_display
::
overlay_dot
overlay_dot
;
perspective_window
(
);
/*!
ensures
- The window is displayed on the screen and is 100x100 pixels in size.
!*/
perspective_window
(
const
std
::
vector
<
dlib
::
vector
<
double
>
>&
point_cloud
);
/*!
ensures
- The window is displayed on the screen and is 100x100 pixels in size.
- This window will have point_cloud added to it via add_overlay() and the
points will all be white.
!*/
perspective_window
(
const
std
::
vector
<
dlib
::
vector
<
double
>
>&
point_cloud
,
const
std
::
string
&
title
);
/*!
ensures
- The window is displayed on the screen and is 100x100 pixels in size.
- This window will have point_cloud added to it via add_overlay() and the
points will all be white.
- The title of the window will be set to the given title string.
!*/
~
perspective_window
(
);
/*!
ensures
- any resources associated with this object have been released
!*/
void
add_overlay
(
const
std
::
vector
<
overlay_line
>&
overlay
);
/*!
ensures
- Adds the given overlay lines into this object such that it will be
displayed.
!*/
void
add_overlay
(
const
std
::
vector
<
overlay_dot
>&
overlay
);
/*!
ensures
- Adds the given overlay dots into this object such that it will be
displayed.
!*/
void
clear_overlay
(
);
/*!
ensures
- Removes all overlays from this object. The display will be empty.
!*/
void
add_overlay
(
const
std
::
vector
<
dlib
::
vector
<
double
>
>&
d
);
/*!
ensures
- Adds the given dots into this object such that it will be
displayed. They will be colored white.
!*/
template
<
typename
pixel_type
>
void
add_overlay
(
const
std
::
vector
<
dlib
::
vector
<
double
>
>&
d
,
pixel_type
p
);
/*!
ensures
- Adds the given dots into this object such that it will be
displayed. They will be colored by pixel color p.
!*/
template
<
typename
T
>
void
set_dot_double_clicked_handler
(
T
&
object
,
void
(
T
::*
event_handler
)(
const
vector
<
double
>&
)
);
/*
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 double
clicks on one of the overlay dots. The selected dot will be passed to
event_handler().
- 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)
*/
void
set_dot_double_clicked_handler
(
const
any_function
<
void
(
const
vector
<
double
>&
)
>&
event_handler
);
/*
ensures
- The event_handler function is called when the user double clicks on one
of the overlay dots. The selected dot will be passed to event_handler().
- 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)
*/
};
// ----------------------------------------------------------------------------------------
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment