diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 3631a4bea0..93a4dea2e1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -140,13 +140,6 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent) // Private namespace with helper function for create volume namespace priv { -/// -/// Check if volume type is possible use for new text volume -/// -/// Type -/// True when allowed otherwise false -static bool is_valid(ModelVolumeType volume_type); - /// /// Prepare data for emboss /// @@ -249,10 +242,9 @@ static bool apply_camera_dir(const Camera &camera, GLCanvas3D &canvas); void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mouse_pos) { - if (!priv::is_valid(volume_type)) return; - m_style_manager.discard_style_changes(); - set_default_text(); - + if (!init_create(volume_type)) + return; + GLVolume *gl_volume = get_first_hovered_gl_volume(m_parent); DataBase emboss_data = priv::create_emboss_data_base(m_text, m_style_manager, m_job_cancel); if (gl_volume != nullptr) { @@ -271,9 +263,8 @@ void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mous // Designed for create volume without information of mouse in scene void GLGizmoEmboss::create_volume(ModelVolumeType volume_type) { - if (!priv::is_valid(volume_type)) return; - m_style_manager.discard_style_changes(); - set_default_text(); + if (!init_create(volume_type)) + return; // select position by camera position and view direction const Selection &selection = m_parent.get_selection(); @@ -321,6 +312,28 @@ void GLGizmoEmboss::create_volume(ModelVolumeType volume_type) } } +bool GLGizmoEmboss::init_create(ModelVolumeType volume_type) +{ + // check valid volume type + if (volume_type != ModelVolumeType::MODEL_PART && + volume_type != ModelVolumeType::NEGATIVE_VOLUME && + volume_type != ModelVolumeType::PARAMETER_MODIFIER){ + BOOST_LOG_TRIVIAL(error) << "Can't create embossed volume with this type: " << (int) volume_type; + return false; + } + + if (!is_activable()) { + BOOST_LOG_TRIVIAL(error) << "Can't create text. Gizmo is not activabled."; + return false; + } + + m_style_manager.discard_style_changes(); + + // set default text + m_text = _u8L("Embossed text"); + return true; +} + bool GLGizmoEmboss::on_mouse_for_rotation(const wxMouseEvent &mouse_event) { if (mouse_event.Moving()) return false; @@ -510,6 +523,8 @@ bool GLGizmoEmboss::on_init() m_rotate_gizmo.init(); ColorRGBA gray_color(.6f, .6f, .6f, .3f); m_rotate_gizmo.set_highlight_color(gray_color); + + // NOTE: It has special handling in GLGizmosManager::handle_shortcut m_shortcut_key = WXK_CONTROL_T; // initialize text styles @@ -520,6 +535,11 @@ bool GLGizmoEmboss::on_init() return true; } +bool GLGizmoEmboss::on_is_activable() const { + return wxGetApp().get_mode() != comSimple && + !wxGetApp().obj_list()->has_selected_cut_object(); +} + std::string GLGizmoEmboss::on_get_name() const { return _u8L("Emboss"); } void GLGizmoEmboss::on_render() { @@ -729,34 +749,33 @@ void GLGizmoEmboss::on_set_state() { // enable / disable bed from picking // Rotation gizmo must work through bed - m_parent.set_raycaster_gizmos_on_top(GLGizmoBase::m_state == GLGizmoBase::On); + m_parent.set_raycaster_gizmos_on_top(m_state == GLGizmoBase::On); - m_rotate_gizmo.set_state(GLGizmoBase::m_state); + m_rotate_gizmo.set_state(m_state); // Closing gizmo. e.g. selecting another one - if (GLGizmoBase::m_state == GLGizmoBase::Off) { + if (m_state == GLGizmoBase::Off) { // refuse outgoing during text preview - if (false) { - GLGizmoBase::m_state = GLGizmoBase::On; - auto notification_manager = wxGetApp().plater()->get_notification_manager(); - notification_manager->push_notification( - NotificationType::CustomNotification, - NotificationManager::NotificationLevel::RegularNotificationLevel, - _u8L("ERROR: Wait until ends or Cancel process.")); - return; - } reset_volume(); // Store order and last activ index into app.ini // TODO: what to do when can't store into file? m_style_manager.store_styles_to_app_config(false); remove_notification_not_valid_font(); - } else if (GLGizmoBase::m_state == GLGizmoBase::On) { + } else if (m_state == GLGizmoBase::On) { // to reload fonts from system, when install new one wxFontEnumerator::InvalidateCache(); // Immediately after set state On is called function data_changed(), // where one could distiguish undo/redo serialization from opening by letter 'T' - //set_volume_by_selection(); + set_volume_by_selection(); + + // when open window by "T" and no valid volume is selected, so Create new one + if (m_volume == nullptr) { + // reopen gizmo when new object is created + m_state = GLGizmoBase::Off; + // start creating new object + return; + } m_is_just_opened = true; // change position of just opened emboss window @@ -778,21 +797,7 @@ void GLGizmoEmboss::on_set_state() void GLGizmoEmboss::data_changed(bool is_serializing) { if (is_serializing) reset_volume(); - set_volume_by_selection(); - - // when open window by "T" and no valid volume is selected, so Create new one - // this is only place where One could distiguish between serializing and open by shortcut T - if (!is_serializing && m_is_just_opened && m_volume == nullptr) { - // reopen gizmo when new object is created - close(); - if (wxGetApp().get_mode() == comSimple || wxGetApp().obj_list()->has_selected_cut_object()) - // It's unwanted to add a part in simple mode - return; - - // start creating new object - create_volume(ModelVolumeType::MODEL_PART); - } } void GLGizmoEmboss::on_start_dragging() { m_rotate_gizmo.start_dragging(); } @@ -989,8 +994,6 @@ EmbossStyles GLGizmoEmboss::create_default_styles() return styles; } -void GLGizmoEmboss::set_default_text(){ m_text = _u8L("Embossed text"); } - void GLGizmoEmboss::set_volume_by_selection() { const Selection &selection = m_parent.get_selection(); @@ -3402,16 +3405,6 @@ bool priv::draw_button(const IconManager::VIcons &icons, IconType type, bool dis // priv namespace implementation /////////////// -bool priv::is_valid(ModelVolumeType volume_type) -{ - if (volume_type == ModelVolumeType::MODEL_PART || volume_type == ModelVolumeType::NEGATIVE_VOLUME || - volume_type == ModelVolumeType::PARAMETER_MODIFIER) - return true; - - BOOST_LOG_TRIVIAL(error) << "Can't create embossed volume with this type: " << (int) volume_type; - return false; -} - DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &style_manager, std::shared_ptr>& cancel) { // create volume_name @@ -3421,9 +3414,12 @@ DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &st // change enters to space std::replace(volume_name.begin(), volume_name.end(), '\n', ' '); - if (!style_manager.is_active_font()) + if (!style_manager.is_active_font()) { style_manager.load_valid_style(); - assert(style_manager.is_active_font()); + assert(style_manager.is_active_font()); + if (!style_manager.is_active_font()) + return {}; // no active font in style, should never happend !!! + } const EmbossStyle &es = style_manager.get_style(); // actualize font path - during changes in gui it could be corrupted diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 5683820c5e..5f68175954 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -49,12 +49,12 @@ public: protected: bool on_init() override; + bool on_is_activable() const override; std::string on_get_name() const override; void on_render() override; - virtual void on_register_raycasters_for_picking() override; - virtual void on_unregister_raycasters_for_picking() override; + void on_register_raycasters_for_picking() override; + void on_unregister_raycasters_for_picking() override; void on_render_input_window(float x, float y, float bottom_limit) override; - bool on_is_activable() const override { return true; } bool on_is_selectable() const override { return false; } void on_set_state() override; void data_changed(bool is_serializing) override; // selection changed @@ -79,7 +79,7 @@ protected: private: static EmbossStyles create_default_styles(); // localized default text - void set_default_text(); + bool init_create(ModelVolumeType volume_type); void set_volume_by_selection(); void reset_volume(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 361fd77928..4dfaff09f0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -238,15 +238,24 @@ bool GLGizmosManager::is_running() const bool GLGizmosManager::handle_shortcut(int key) { - if (!m_enabled || m_parent.get_selection().is_empty()) + if (!m_enabled) return false; - auto it = std::find_if(m_gizmos.begin(), m_gizmos.end(), - [key](const std::unique_ptr& gizmo) { - int gizmo_key = gizmo->get_shortcut_key(); - return gizmo->is_activable() - && ((gizmo_key == key - 64) || (gizmo_key == key - 96)); - }); + auto is_key = [pressed_key = key](int gizmo_key) { return (gizmo_key == pressed_key - 64) || (gizmo_key == pressed_key - 96); }; + // allowe open shortcut even when selection is empty + if (GLGizmoBase* gizmo_emboss = m_gizmos[Emboss].get(); + is_key(gizmo_emboss->get_shortcut_key())) { + dynamic_cast(gizmo_emboss)->create_volume(ModelVolumeType::MODEL_PART); + return true; + } + + if (m_parent.get_selection().is_empty()) + return false; + + auto is_gizmo = [is_key](const std::unique_ptr &gizmo) { + return gizmo->is_activable() && is_key(gizmo->get_shortcut_key()); + }; + auto it = std::find_if(m_gizmos.begin(), m_gizmos.end(), is_gizmo); if (it == m_gizmos.end()) return false;