3D scene toolbar actions

This commit is contained in:
Enrico Turri 2018-07-27 12:08:33 +02:00
parent a3cdc7e408
commit ddda5062c2
10 changed files with 749 additions and 20 deletions

View File

@ -159,7 +159,63 @@ sub new {
}
}
};
#======================================================================================================================================================
# callbacks for toolbar
my $on_action_add = sub {
$self->add;
};
my $on_action_delete = sub {
$self->remove();
};
my $on_action_deleteall = sub {
$self->reset;
};
my $on_action_arrange = sub {
$self->arrange;
};
my $on_action_more = sub {
$self->increase;
};
my $on_action_fewer = sub {
$self->decrease;
};
my $on_action_ccw45 = sub {
$self->rotate(45, Z, 'relative');
};
my $on_action_cw45 = sub {
$self->rotate(-45, Z, 'relative');
};
my $on_action_scale = sub {
$self->changescale(undef);
};
my $on_action_split = sub {
$self->split_object;
};
my $on_action_cut = sub {
$self->object_cut_dialog;
};
my $on_action_settings = sub {
$self->object_settings_dialog;
};
my $on_action_layersediting = sub {
my $state = Slic3r::GUI::_3DScene::is_toolbar_item_pressed($self->{canvas3D}, "layersediting");
$self->on_layer_editing_toggled($state);
};
#======================================================================================================================================================
# Initialize 3D plater
if ($Slic3r::GUI::have_OpenGL) {
$self->{canvas3D} = Slic3r::GUI::Plater::3D->new($self->{preview_notebook}, $self->{objects}, $self->{model}, $self->{print}, $self->{config});
@ -179,6 +235,21 @@ sub new {
Slic3r::GUI::_3DScene::register_on_gizmo_scale_uniformly_callback($self->{canvas3D}, $on_gizmo_scale_uniformly);
Slic3r::GUI::_3DScene::register_on_gizmo_rotate_callback($self->{canvas3D}, $on_gizmo_rotate);
Slic3r::GUI::_3DScene::register_on_update_geometry_info_callback($self->{canvas3D}, $on_update_geometry_info);
#======================================================================================================================================================
Slic3r::GUI::_3DScene::register_action_add_callback($self->{canvas3D}, $on_action_add);
Slic3r::GUI::_3DScene::register_action_delete_callback($self->{canvas3D}, $on_action_delete);
Slic3r::GUI::_3DScene::register_action_deleteall_callback($self->{canvas3D}, $on_action_deleteall);
Slic3r::GUI::_3DScene::register_action_arrange_callback($self->{canvas3D}, $on_action_arrange);
Slic3r::GUI::_3DScene::register_action_more_callback($self->{canvas3D}, $on_action_more);
Slic3r::GUI::_3DScene::register_action_fewer_callback($self->{canvas3D}, $on_action_fewer);
Slic3r::GUI::_3DScene::register_action_ccw45_callback($self->{canvas3D}, $on_action_ccw45);
Slic3r::GUI::_3DScene::register_action_cw45_callback($self->{canvas3D}, $on_action_cw45);
Slic3r::GUI::_3DScene::register_action_scale_callback($self->{canvas3D}, $on_action_scale);
Slic3r::GUI::_3DScene::register_action_split_callback($self->{canvas3D}, $on_action_split);
Slic3r::GUI::_3DScene::register_action_cut_callback($self->{canvas3D}, $on_action_cut);
Slic3r::GUI::_3DScene::register_action_settings_callback($self->{canvas3D}, $on_action_settings);
Slic3r::GUI::_3DScene::register_action_layersediting_callback($self->{canvas3D}, $on_action_layersediting);
#======================================================================================================================================================
Slic3r::GUI::_3DScene::enable_gizmos($self->{canvas3D}, 1);
#======================================================================================================================================================
Slic3r::GUI::_3DScene::enable_toolbar($self->{canvas3D}, 1);
@ -2098,25 +2169,32 @@ sub object_list_changed {
# Enable/disable buttons depending on whether there are any objects on the platter.
my $have_objects = @{$self->{objects}} ? 1 : 0;
my $variable_layer_height_allowed = $self->{config}->variable_layer_height && Slic3r::GUI::_3DScene::is_layers_editing_allowed($self->{canvas3D});
#===================================================================================================================================================
# my $variable_layer_height_allowed = $self->{config}->variable_layer_height && Slic3r::GUI::_3DScene::is_layers_editing_allowed($self->{canvas3D});
#===================================================================================================================================================
if ($self->{htoolbar}) {
# On OSX or Linux
$self->{htoolbar}->EnableTool($_, $have_objects)
for (TB_RESET, TB_ARRANGE, TB_LAYER_EDITING);
$self->{htoolbar}->EnableTool(TB_LAYER_EDITING, 0) if (! $variable_layer_height_allowed);
#===================================================================================================================================================
for (TB_RESET, TB_ARRANGE);
# for (TB_RESET, TB_ARRANGE, TB_LAYER_EDITING);
# $self->{htoolbar}->EnableTool(TB_LAYER_EDITING, 0) if (! $variable_layer_height_allowed);
#===================================================================================================================================================
} else {
# On MSW
my $method = $have_objects ? 'Enable' : 'Disable';
$self->{"btn_$_"}->$method
for grep $self->{"btn_$_"}, qw(reset arrange reslice export_gcode export_stl print send_gcode layer_editing);
$self->{"btn_layer_editing"}->Disable if (! $variable_layer_height_allowed);
#===================================================================================================================================================
for grep $self->{"btn_$_"}, qw(reset arrange reslice export_gcode export_stl print send_gcode);
# for grep $self->{"btn_$_"}, qw(reset arrange reslice export_gcode export_stl print send_gcode layer_editing);
# $self->{"btn_layer_editing"}->Disable if (! $variable_layer_height_allowed);
#===================================================================================================================================================
}
#===================================================================================================================================================
for my $toolbar_item (qw(deleteall arrange layersediting)) {
for my $toolbar_item (qw(deleteall arrange)) {
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, $toolbar_item, $have_objects);
}
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "layersediting", 0) if (! $variable_layer_height_allowed);
#===================================================================================================================================================
my $export_in_progress = $self->{export_gcode_output_file} || $self->{send_gcode_file};
@ -2132,23 +2210,41 @@ sub selection_changed {
my ($self) = @_;
my ($obj_idx, $object) = $self->selected_object;
my $have_sel = defined $obj_idx;
#===================================================================================================================================================
my $layers_height_allowed = $self->{config}->variable_layer_height && Slic3r::GUI::_3DScene::is_layers_editing_allowed($self->{canvas3D}) && $have_sel;
#===================================================================================================================================================
$self->{right_panel}->Freeze;
if ($self->{htoolbar}) {
# On OSX or Linux
$self->{htoolbar}->EnableTool($_, $have_sel)
for (TB_REMOVE, TB_MORE, TB_FEWER, TB_45CW, TB_45CCW, TB_SCALE, TB_SPLIT, TB_CUT, TB_SETTINGS);
#===================================================================================================================================================
$self->{htoolbar}->EnableTool(TB_LAYER_EDITING, $layers_height_allowed);
#===================================================================================================================================================
} else {
# On MSW
my $method = $have_sel ? 'Enable' : 'Disable';
$self->{"btn_$_"}->$method
for grep $self->{"btn_$_"}, qw(remove increase decrease rotate45cw rotate45ccw changescale split cut settings);
#===================================================================================================================================================
if ($layers_height_allowed) {
$self->{"btn_layer_editing"}->Enable;
} else {
$self->{"btn_layer_editing"}->Disable;
}
#===================================================================================================================================================
}
#===================================================================================================================================================
for my $toolbar_item (qw(delete more fewer ccw45 cw45 scale split cut settings)) {
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, $toolbar_item, $have_sel);
}
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "layersediting", $layers_height_allowed);
#===================================================================================================================================================
if ($self->{object_info_size}) { # have we already loaded the info pane?

View File

@ -1803,6 +1803,11 @@ void _3DScene::enable_toolbar_item(wxGLCanvas* canvas, const std::string& name,
{
s_canvas_mgr.enable_toolbar_item(canvas, name, enable);
}
bool _3DScene::is_toolbar_item_pressed(wxGLCanvas* canvas, const std::string& name)
{
return s_canvas_mgr.is_toolbar_item_pressed(canvas, name);
}
//###################################################################################################################################
void _3DScene::zoom_to_bed(wxGLCanvas* canvas)
@ -1940,6 +1945,73 @@ void _3DScene::register_on_update_geometry_info_callback(wxGLCanvas* canvas, voi
s_canvas_mgr.register_on_update_geometry_info_callback(canvas, callback);
}
//###################################################################################################################################
void _3DScene::register_action_add_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_add_callback(canvas, callback);
}
void _3DScene::register_action_delete_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_delete_callback(canvas, callback);
}
void _3DScene::register_action_deleteall_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_deleteall_callback(canvas, callback);
}
void _3DScene::register_action_arrange_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_arrange_callback(canvas, callback);
}
void _3DScene::register_action_more_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_more_callback(canvas, callback);
}
void _3DScene::register_action_fewer_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_fewer_callback(canvas, callback);
}
void _3DScene::register_action_ccw45_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_ccw45_callback(canvas, callback);
}
void _3DScene::register_action_cw45_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_cw45_callback(canvas, callback);
}
void _3DScene::register_action_scale_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_scale_callback(canvas, callback);
}
void _3DScene::register_action_split_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_split_callback(canvas, callback);
}
void _3DScene::register_action_cut_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_cut_callback(canvas, callback);
}
void _3DScene::register_action_settings_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_settings_callback(canvas, callback);
}
void _3DScene::register_action_layersediting_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_action_layersediting_callback(canvas, callback);
}
//###################################################################################################################################
static inline int hex_digit_to_int(const char c)
{
return

View File

@ -504,6 +504,7 @@ public:
//###################################################################################################################################
static void enable_toolbar_item(wxGLCanvas* canvas, const std::string& name, bool enable);
static bool is_toolbar_item_pressed(wxGLCanvas* canvas, const std::string& name);
//###################################################################################################################################
static void zoom_to_bed(wxGLCanvas* canvas);
@ -538,6 +539,22 @@ public:
static void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
static void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
//###################################################################################################################################
static void register_action_add_callback(wxGLCanvas* canvas, void* callback);
static void register_action_delete_callback(wxGLCanvas* canvas, void* callback);
static void register_action_deleteall_callback(wxGLCanvas* canvas, void* callback);
static void register_action_arrange_callback(wxGLCanvas* canvas, void* callback);
static void register_action_more_callback(wxGLCanvas* canvas, void* callback);
static void register_action_fewer_callback(wxGLCanvas* canvas, void* callback);
static void register_action_ccw45_callback(wxGLCanvas* canvas, void* callback);
static void register_action_cw45_callback(wxGLCanvas* canvas, void* callback);
static void register_action_scale_callback(wxGLCanvas* canvas, void* callback);
static void register_action_split_callback(wxGLCanvas* canvas, void* callback);
static void register_action_cut_callback(wxGLCanvas* canvas, void* callback);
static void register_action_settings_callback(wxGLCanvas* canvas, void* callback);
static void register_action_layersediting_callback(wxGLCanvas* canvas, void* callback);
//###################################################################################################################################
static std::vector<int> load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs);
static std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);

View File

@ -1698,6 +1698,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
, m_force_zoom_to_bed_enabled(false)
, m_apply_zoom_to_volumes_filter(false)
, m_hover_volume_id(-1)
//###################################################################################################################################
, m_toolbar_action_running(false)
//###################################################################################################################################
, m_warning_texture_enabled(false)
, m_legend_texture_enabled(false)
, m_picking_enabled(false)
@ -2090,6 +2093,11 @@ void GLCanvas3D::enable_toolbar_item(const std::string& name, bool enable)
else
m_toolbar.disable_item(name);
}
bool GLCanvas3D::is_toolbar_item_pressed(const std::string& name) const
{
return m_toolbar.is_item_pressed(name);
}
//###################################################################################################################################
void GLCanvas3D::zoom_to_bed()
@ -2862,6 +2870,86 @@ void GLCanvas3D::register_on_update_geometry_info_callback(void* callback)
m_on_update_geometry_info_callback.register_callback(callback);
}
//###################################################################################################################################
void GLCanvas3D::register_action_add_callback(void* callback)
{
if (callback != nullptr)
m_action_add_callback.register_callback(callback);
}
void GLCanvas3D::register_action_delete_callback(void* callback)
{
if (callback != nullptr)
m_action_delete_callback.register_callback(callback);
}
void GLCanvas3D::register_action_deleteall_callback(void* callback)
{
if (callback != nullptr)
m_action_deleteall_callback.register_callback(callback);
}
void GLCanvas3D::register_action_arrange_callback(void* callback)
{
if (callback != nullptr)
m_action_arrange_callback.register_callback(callback);
}
void GLCanvas3D::register_action_more_callback(void* callback)
{
if (callback != nullptr)
m_action_more_callback.register_callback(callback);
}
void GLCanvas3D::register_action_fewer_callback(void* callback)
{
if (callback != nullptr)
m_action_fewer_callback.register_callback(callback);
}
void GLCanvas3D::register_action_ccw45_callback(void* callback)
{
if (callback != nullptr)
m_action_ccw45_callback.register_callback(callback);
}
void GLCanvas3D::register_action_cw45_callback(void* callback)
{
if (callback != nullptr)
m_action_cw45_callback.register_callback(callback);
}
void GLCanvas3D::register_action_scale_callback(void* callback)
{
if (callback != nullptr)
m_action_scale_callback.register_callback(callback);
}
void GLCanvas3D::register_action_split_callback(void* callback)
{
if (callback != nullptr)
m_action_split_callback.register_callback(callback);
}
void GLCanvas3D::register_action_cut_callback(void* callback)
{
if (callback != nullptr)
m_action_cut_callback.register_callback(callback);
}
void GLCanvas3D::register_action_settings_callback(void* callback)
{
if (callback != nullptr)
m_action_settings_callback.register_callback(callback);
}
void GLCanvas3D::register_action_layersediting_callback(void* callback)
{
if (callback != nullptr)
m_action_layersediting_callback.register_callback(callback);
}
//###################################################################################################################################
void GLCanvas3D::bind_event_handlers()
{
if (m_canvas != nullptr)
@ -3039,6 +3127,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1;
m_layers_editing.last_object_id = layer_editing_object_idx;
bool gizmos_overlay_contains_mouse = m_gizmos.overlay_contains_mouse(*this, m_mouse.position);
//###################################################################################################################################
int toolbar_contains_mouse = m_toolbar.contains_mouse(*this, m_mouse.position);
//###################################################################################################################################
if (evt.Entering())
{
@ -3052,6 +3143,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
else if (evt.LeftDClick() && (m_hover_volume_id != -1))
m_on_double_click_callback.call();
//###################################################################################################################################
else if (evt.LeftDClick() && (toolbar_contains_mouse != -1))
{
m_toolbar_action_running = true;
m_toolbar.do_action((unsigned int)toolbar_contains_mouse, *this);
}
//###################################################################################################################################
else if (evt.LeftDown() || evt.RightDown())
{
// If user pressed left or right button we first check whether this happened
@ -3090,6 +3188,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.drag.gizmo_volume_idx = _get_first_selected_volume_id();
m_dirty = true;
}
//###################################################################################################################################
else if (toolbar_contains_mouse != -1)
{
m_toolbar_action_running = true;
m_toolbar.do_action((unsigned int)toolbar_contains_mouse, *this);
}
//###################################################################################################################################
else
{
// Select volume in this 3D canvas.
@ -3346,7 +3451,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
else if (!m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() && !is_layers_editing_enabled())
{
// deselect and propagate event through callback
if (m_picking_enabled)
//###################################################################################################################################
if (m_picking_enabled && !m_toolbar_action_running)
// if (m_picking_enabled)
//###################################################################################################################################
{
deselect_volumes();
_on_select(-1);
@ -3378,6 +3486,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.set_start_position_3D_as_invalid();
m_mouse.set_start_position_2D_as_invalid();
m_mouse.dragging = false;
//###################################################################################################################################
m_toolbar_action_running = false;
//###################################################################################################################################
m_dirty = true;
}
else if (evt.Moving())
@ -3467,36 +3578,48 @@ bool GLCanvas3D::_init_toolbar()
item.name = "add";
item.tooltip = GUI::L_str("Add...");
item.is_toggable = false;
item.action_callback = &m_action_add_callback;
item.textures[GLToolbarItem::Normal] = "brick_add_normal_36.png";
item.textures[GLToolbarItem::Hover] = "brick_add_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "brick_add_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "brick_add_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "brick_add_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "delete";
item.tooltip = GUI::L_str("Delete");
item.is_toggable = false;
item.action_callback = &m_action_delete_callback;
item.textures[GLToolbarItem::Normal] = "brick_delete_normal_36.png";
item.textures[GLToolbarItem::Hover] = "brick_delete_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "brick_delete_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "brick_delete_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "brick_delete_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "deleteall";
item.tooltip = GUI::L_str("Delete all");
item.is_toggable = false;
item.action_callback = &m_action_deleteall_callback;
item.textures[GLToolbarItem::Normal] = "cross_normal_36.png";
item.textures[GLToolbarItem::Hover] = "cross_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "cross_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "cross_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "cross_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "arrange";
item.tooltip = GUI::L_str("Arrange");
item.is_toggable = false;
item.action_callback = &m_action_arrange_callback;
item.textures[GLToolbarItem::Normal] = "bricks_normal_36.png";
item.textures[GLToolbarItem::Hover] = "bricks_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "bricks_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "bricks_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "bricks_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
@ -3506,18 +3629,24 @@ bool GLCanvas3D::_init_toolbar()
item.name = "more";
item.tooltip = GUI::L_str("Add instance");
item.is_toggable = false;
item.action_callback = &m_action_more_callback;
item.textures[GLToolbarItem::Normal] = "add_normal_36.png";
item.textures[GLToolbarItem::Hover] = "add_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "add_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "add_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "add_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "fewer";
item.tooltip = GUI::L_str("Remove instance");
item.is_toggable = false;
item.action_callback = &m_action_fewer_callback;
item.textures[GLToolbarItem::Normal] = "delete_normal_36.png";
item.textures[GLToolbarItem::Hover] = "delete_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "delete_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "delete_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "delete_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
@ -3527,45 +3656,60 @@ bool GLCanvas3D::_init_toolbar()
item.name = "ccw45";
item.tooltip = GUI::L_str("Rotate CCW 45 degrees");
item.is_toggable = false;
item.action_callback = &m_action_ccw45_callback;
item.textures[GLToolbarItem::Normal] = "arrow_rotate_anticlockwise_normal_36.png";
item.textures[GLToolbarItem::Hover] = "arrow_rotate_anticlockwise_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "arrow_rotate_anticlockwise_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "arrow_rotate_anticlockwise_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "arrow_rotate_anticlockwise_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "cw45";
item.tooltip = GUI::L_str("Rotate CW 45 degrees");
item.is_toggable = false;
item.action_callback = &m_action_cw45_callback;
item.textures[GLToolbarItem::Normal] = "arrow_rotate_clockwise_normal_36.png";
item.textures[GLToolbarItem::Hover] = "arrow_rotate_clockwise_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "arrow_rotate_clockwise_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "arrow_rotate_clockwise_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "arrow_rotate_clockwise_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "scale";
item.tooltip = GUI::L_str("Scale...");
item.is_toggable = false;
item.action_callback = &m_action_scale_callback;
item.textures[GLToolbarItem::Normal] = "arrow_out_normal_36.png";
item.textures[GLToolbarItem::Hover] = "arrow_out_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "arrow_out_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "arrow_out_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "arrow_out_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "split";
item.tooltip = GUI::L_str("Split");
item.is_toggable = false;
item.action_callback = &m_action_split_callback;
item.textures[GLToolbarItem::Normal] = "shape_ungroup_normal_36.png";
item.textures[GLToolbarItem::Hover] = "shape_ungroup_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "shape_ungroup_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "shape_ungroup_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "shape_ungroup_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "cut";
item.tooltip = GUI::L_str("Cut...");
item.is_toggable = false;
item.action_callback = &m_action_cut_callback;
item.textures[GLToolbarItem::Normal] = "package_normal_36.png";
item.textures[GLToolbarItem::Hover] = "package_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "package_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "package_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "package_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
@ -3575,18 +3719,24 @@ bool GLCanvas3D::_init_toolbar()
item.name = "settings";
item.tooltip = GUI::L_str("Settings...");
item.is_toggable = false;
item.action_callback = &m_action_settings_callback;
item.textures[GLToolbarItem::Normal] = "cog_normal_36.png";
item.textures[GLToolbarItem::Hover] = "cog_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "cog_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "cog_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "cog_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
item.name = "layersediting";
item.tooltip = GUI::L_str("Layers editing");
item.is_toggable = true;
item.action_callback = &m_action_layersediting_callback;
item.textures[GLToolbarItem::Normal] = "variable_layer_height_normal_36.png";
item.textures[GLToolbarItem::Hover] = "variable_layer_height_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "variable_layer_height_pressed_36.png";
item.textures[GLToolbarItem::HoverPressed] = "variable_layer_height_hover_pressed_36.png";
item.textures[GLToolbarItem::Disabled] = "variable_layer_height_disabled_36.png";
if (!m_toolbar.add_item(item))
return false;
@ -3786,6 +3936,22 @@ void GLCanvas3D::_deregister_callbacks()
m_on_gizmo_scale_uniformly_callback.deregister_callback();
m_on_gizmo_rotate_callback.deregister_callback();
m_on_update_geometry_info_callback.deregister_callback();
//###################################################################################################################################
m_action_add_callback.deregister_callback();
m_action_delete_callback.deregister_callback();
m_action_deleteall_callback.deregister_callback();
m_action_arrange_callback.deregister_callback();
m_action_more_callback.deregister_callback();
m_action_fewer_callback.deregister_callback();
m_action_ccw45_callback.deregister_callback();
m_action_cw45_callback.deregister_callback();
m_action_scale_callback.deregister_callback();
m_action_split_callback.deregister_callback();
m_action_cut_callback.deregister_callback();
m_action_settings_callback.deregister_callback();
m_action_layersediting_callback.deregister_callback();
//###################################################################################################################################
}
void GLCanvas3D::_mark_volumes_for_layer_height() const

View File

@ -450,6 +450,9 @@ private:
bool m_force_zoom_to_bed_enabled;
bool m_apply_zoom_to_volumes_filter;
mutable int m_hover_volume_id;
//###################################################################################################################################
bool m_toolbar_action_running;
//###################################################################################################################################
bool m_warning_texture_enabled;
bool m_legend_texture_enabled;
bool m_picking_enabled;
@ -486,6 +489,22 @@ private:
PerlCallback m_on_gizmo_rotate_callback;
PerlCallback m_on_update_geometry_info_callback;
//###################################################################################################################################
PerlCallback m_action_add_callback;
PerlCallback m_action_delete_callback;
PerlCallback m_action_deleteall_callback;
PerlCallback m_action_arrange_callback;
PerlCallback m_action_more_callback;
PerlCallback m_action_fewer_callback;
PerlCallback m_action_ccw45_callback;
PerlCallback m_action_cw45_callback;
PerlCallback m_action_scale_callback;
PerlCallback m_action_split_callback;
PerlCallback m_action_cut_callback;
PerlCallback m_action_settings_callback;
PerlCallback m_action_layersediting_callback;
//###################################################################################################################################
public:
GLCanvas3D(wxGLCanvas* canvas);
~GLCanvas3D();
@ -552,6 +571,7 @@ public:
//###################################################################################################################################
void enable_toolbar_item(const std::string& name, bool enable);
bool is_toolbar_item_pressed(const std::string& name) const;
//###################################################################################################################################
void zoom_to_bed();
@ -602,6 +622,22 @@ public:
void register_on_gizmo_rotate_callback(void* callback);
void register_on_update_geometry_info_callback(void* callback);
//###################################################################################################################################
void register_action_add_callback(void* callback);
void register_action_delete_callback(void* callback);
void register_action_deleteall_callback(void* callback);
void register_action_arrange_callback(void* callback);
void register_action_more_callback(void* callback);
void register_action_fewer_callback(void* callback);
void register_action_ccw45_callback(void* callback);
void register_action_cw45_callback(void* callback);
void register_action_scale_callback(void* callback);
void register_action_split_callback(void* callback);
void register_action_cut_callback(void* callback);
void register_action_settings_callback(void* callback);
void register_action_layersediting_callback(void* callback);
//###################################################################################################################################
void bind_event_handlers();
void unbind_event_handlers();

View File

@ -441,6 +441,12 @@ void GLCanvas3DManager::enable_toolbar_item(wxGLCanvas* canvas, const std::strin
if (it != m_canvases.end())
it->second->enable_toolbar_item(name, enable);
}
bool GLCanvas3DManager::is_toolbar_item_pressed(wxGLCanvas* canvas, const std::string& name) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->is_toolbar_item_pressed(name) : false;
}
//###################################################################################################################################
void GLCanvas3DManager::zoom_to_bed(wxGLCanvas* canvas)
@ -703,6 +709,99 @@ void GLCanvas3DManager::register_on_update_geometry_info_callback(wxGLCanvas* ca
it->second->register_on_update_geometry_info_callback(callback);
}
//###################################################################################################################################
void GLCanvas3DManager::register_action_add_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_add_callback(callback);
}
void GLCanvas3DManager::register_action_delete_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_delete_callback(callback);
}
void GLCanvas3DManager::register_action_deleteall_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_deleteall_callback(callback);
}
void GLCanvas3DManager::register_action_arrange_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_arrange_callback(callback);
}
void GLCanvas3DManager::register_action_more_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_more_callback(callback);
}
void GLCanvas3DManager::register_action_fewer_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_fewer_callback(callback);
}
void GLCanvas3DManager::register_action_ccw45_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_ccw45_callback(callback);
}
void GLCanvas3DManager::register_action_cw45_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_cw45_callback(callback);
}
void GLCanvas3DManager::register_action_scale_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_scale_callback(callback);
}
void GLCanvas3DManager::register_action_split_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_split_callback(callback);
}
void GLCanvas3DManager::register_action_cut_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_cut_callback(callback);
}
void GLCanvas3DManager::register_action_settings_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_settings_callback(callback);
}
void GLCanvas3DManager::register_action_layersediting_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_action_layersediting_callback(callback);
}
//###################################################################################################################################
GLCanvas3DManager::CanvasesMap::iterator GLCanvas3DManager::_get_canvas(wxGLCanvas* canvas)
{
return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);

View File

@ -119,6 +119,7 @@ public:
//###################################################################################################################################
void enable_toolbar_item(wxGLCanvas* canvas, const std::string& name, bool enable);
bool is_toolbar_item_pressed(wxGLCanvas* canvas, const std::string& name) const;
//###################################################################################################################################
void zoom_to_bed(wxGLCanvas* canvas);
@ -165,6 +166,22 @@ public:
void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
//###################################################################################################################################
void register_action_add_callback(wxGLCanvas* canvas, void* callback);
void register_action_delete_callback(wxGLCanvas* canvas, void* callback);
void register_action_deleteall_callback(wxGLCanvas* canvas, void* callback);
void register_action_arrange_callback(wxGLCanvas* canvas, void* callback);
void register_action_more_callback(wxGLCanvas* canvas, void* callback);
void register_action_fewer_callback(wxGLCanvas* canvas, void* callback);
void register_action_ccw45_callback(wxGLCanvas* canvas, void* callback);
void register_action_cw45_callback(wxGLCanvas* canvas, void* callback);
void register_action_scale_callback(wxGLCanvas* canvas, void* callback);
void register_action_split_callback(wxGLCanvas* canvas, void* callback);
void register_action_cut_callback(wxGLCanvas* canvas, void* callback);
void register_action_settings_callback(wxGLCanvas* canvas, void* callback);
void register_action_layersediting_callback(wxGLCanvas* canvas, void* callback);
//###################################################################################################################################
private:
CanvasesMap::iterator _get_canvas(wxGLCanvas* canvas);
CanvasesMap::const_iterator _get_canvas(wxGLCanvas* canvas) const;

View File

@ -1,6 +1,5 @@
#include "GLToolbar.hpp"
#include "../../libslic3r/Utils.hpp"
#include "../../slic3r/GUI/GLCanvas3D.hpp"
#include <GL/glew.h>
@ -12,11 +11,13 @@
namespace Slic3r {
namespace GUI {
GLToolbarItem::GLToolbarItem(EType type, const std::string& name, const std::string& tooltip)
GLToolbarItem::GLToolbarItem(EType type, const std::string& name, const std::string& tooltip, bool is_toggable, PerlCallback* action_callback)
: m_type(type)
, m_state(Disabled)
, m_name(name)
, m_tooltip(tooltip)
, m_is_toggable(is_toggable)
, m_action_callback(action_callback)
{
}
@ -29,9 +30,12 @@ bool GLToolbarItem::load_textures(const std::string* filenames)
for (unsigned int i = (unsigned int)Normal; i < (unsigned int)Num_States; ++i)
{
std::string filename = path + filenames[i];
if (!m_icon_textures[i].load_from_file(filename, false))
return false;
if (!filenames[i].empty())
{
std::string filename = path + filenames[i];
if (!m_icon_textures[i].load_from_file(filename, false))
return false;
}
}
return true;
@ -67,6 +71,22 @@ int GLToolbarItem::get_icon_textures_size() const
return m_icon_textures[Normal].get_width();
}
void GLToolbarItem::do_action()
{
if (m_action_callback != nullptr)
m_action_callback->call();
}
bool GLToolbarItem::is_enabled() const
{
return m_state != Disabled;
}
bool GLToolbarItem::is_toggable() const
{
return m_is_toggable;
}
bool GLToolbarItem::is_separator() const
{
return m_type == Separator;
@ -113,7 +133,7 @@ void GLToolbar::set_separator_x(float separator)
bool GLToolbar::add_item(const GLToolbar::ItemCreationData& data)
{
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Action, data.name, data.tooltip);
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Action, data.name, data.tooltip, data.is_toggable, data.action_callback);
if ((item == nullptr) || !item->load_textures(data.textures))
return false;
@ -124,7 +144,7 @@ bool GLToolbar::add_item(const GLToolbar::ItemCreationData& data)
bool GLToolbar::add_separator()
{
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Separator, "", "");
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Separator, "", "", false, nullptr);
if (item == nullptr)
return false;
@ -156,6 +176,17 @@ void GLToolbar::disable_item(const std::string& name)
}
}
bool GLToolbar::is_item_pressed(const std::string& name) const
{
for (GLToolbarItem* item : m_items)
{
if (item->get_name() == name)
return (item->get_state() == GLToolbarItem::Pressed) || (item->get_state() == GLToolbarItem::HoverPressed);
}
return false;
}
void GLToolbar::update_hover_state(GLCanvas3D& canvas, const Pointf& mouse_pos)
{
if (!m_enabled)
@ -201,8 +232,17 @@ void GLToolbar::update_hover_state(GLCanvas3D& canvas, const Pointf& mouse_pos)
}
case GLToolbarItem::Pressed:
{
if (!inside)
item->set_state(GLToolbarItem::Normal);
if (inside)
item->set_state(GLToolbarItem::HoverPressed);
break;
}
case GLToolbarItem::HoverPressed:
{
if (inside)
tooltip = item->get_tooltip();
else
item->set_state(GLToolbarItem::Pressed);
break;
}
@ -219,9 +259,77 @@ void GLToolbar::update_hover_state(GLCanvas3D& canvas, const Pointf& mouse_pos)
canvas.set_tooltip(tooltip);
}
int GLToolbar::contains_mouse(const GLCanvas3D& canvas, const Pointf& mouse_pos) const
{
if (!m_enabled)
return -1;
float cnv_w = (float)canvas.get_canvas_size().get_width();
float width = _get_total_width();
float left = 0.5f * (cnv_w - width);
float top = m_offset_y;
int id = -1;
for (GLToolbarItem* item : m_items)
{
++id;
if (item->is_separator())
left += (m_separator_x + m_gap_x);
else
{
float tex_size = (float)item->get_icon_textures_size() * m_textures_scale;
float right = left + tex_size;
float bottom = top + tex_size;
if ((left <= mouse_pos.x) && (mouse_pos.x <= right) && (top <= mouse_pos.y) && (mouse_pos.y <= bottom))
return id;
left += (tex_size + m_gap_x);
}
}
return -1;
}
void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& canvas)
{
if (item_id < (unsigned int)m_items.size())
{
GLToolbarItem* item = m_items[item_id];
if ((item != nullptr) && !item->is_separator() && item->is_enabled())
{
if (item->is_toggable())
{
GLToolbarItem::EState state = item->get_state();
if (state == GLToolbarItem::Hover)
item->set_state(GLToolbarItem::HoverPressed);
else if (state == GLToolbarItem::HoverPressed)
item->set_state(GLToolbarItem::Hover);
canvas.render();
item->do_action();
}
else
{
item->set_state(GLToolbarItem::HoverPressed);
canvas.render();
item->do_action();
if (item->get_state() != GLToolbarItem::Disabled)
{
// the item may get disabled during the action, if not, set it to normal state
item->set_state(GLToolbarItem::Hover);
canvas.render();
}
}
}
}
}
void GLToolbar::render(const GLCanvas3D& canvas, const Pointf& mouse_pos) const
{
if (m_items.empty())
if (!m_enabled || m_items.empty())
return;
::glDisable(GL_DEPTH_TEST);

View File

@ -2,6 +2,7 @@
#define slic3r_GLToolbar_hpp_
#include "../../slic3r/GUI/GLTexture.hpp"
#include "../../libslic3r/Utils.hpp"
#include <string>
#include <vector>
@ -29,6 +30,7 @@ public:
Normal,
Hover,
Pressed,
HoverPressed,
Disabled,
Num_States
};
@ -43,8 +45,11 @@ private:
std::string m_name;
std::string m_tooltip;
bool m_is_toggable;
PerlCallback* m_action_callback;
public:
GLToolbarItem(EType type, const std::string& name, const std::string& tooltip);
GLToolbarItem(EType type, const std::string& name, const std::string& tooltip, bool is_toggable, PerlCallback* action_callback);
bool load_textures(const std::string* filenames);
@ -58,6 +63,10 @@ public:
unsigned int get_icon_texture_id() const;
int get_icon_textures_size() const;
void do_action();
bool is_enabled() const;
bool is_toggable() const;
bool is_separator() const;
};
@ -68,6 +77,8 @@ public:
{
std::string name;
std::string tooltip;
bool is_toggable;
PerlCallback* action_callback;
std::string textures[GLToolbarItem::Num_States];
};
@ -99,8 +110,15 @@ public:
void enable_item(const std::string& name);
void disable_item(const std::string& name);
bool is_item_pressed(const std::string& name) const;
void update_hover_state(GLCanvas3D& canvas, const Pointf& mouse_pos);
// returns the id of the item under the given mouse position or -1 if none
int contains_mouse(const GLCanvas3D& canvas, const Pointf& mouse_pos) const;
void do_action(unsigned int item_id, GLCanvas3D& canvas);
void render(const GLCanvas3D& canvas, const Pointf& mouse_pos) const;
private:

View File

@ -452,6 +452,15 @@ enable_toolbar_item(canvas, item, enable)
CODE:
_3DScene::enable_toolbar_item((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), item, enable);
bool
is_toolbar_item_pressed(canvas, item)
SV *canvas;
std::string item;
CODE:
RETVAL = _3DScene::is_toolbar_item_pressed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), item);
OUTPUT:
RETVAL
void
zoom_to_bed(canvas)
SV *canvas;
@ -638,7 +647,98 @@ register_on_update_geometry_info_callback(canvas, callback)
SV *callback;
CODE:
_3DScene::register_on_update_geometry_info_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_add_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_add_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_delete_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_delete_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_deleteall_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_deleteall_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_arrange_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_arrange_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_more_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_more_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_fewer_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_fewer_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_ccw45_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_ccw45_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_cw45_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_cw45_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_scale_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_scale_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_split_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_split_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_cut_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_cut_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_settings_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_settings_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_action_layersediting_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_action_layersediting_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
reset_legend_texture()
CODE: