Skip to content

Commit

Permalink
Add text gizmo to right click menu
Browse files Browse the repository at this point in the history
  • Loading branch information
Noisyfox committed Nov 21, 2023
1 parent 2f858db commit 84d7aaa
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 93 deletions.
4 changes: 4 additions & 0 deletions resources/images/add_text_modifier.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions resources/images/add_text_negative.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions resources/images/add_text_part.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/slic3r/GUI/GLCanvas3D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,12 @@ class GLCanvas3D
Size get_canvas_size() const;
Vec2d get_local_mouse_position() const;

// store opening position of menu
std::optional<Vec2d> m_popup_menu_positon; // position of mouse right click
void set_popup_menu_position(const Vec2d &position) { m_popup_menu_positon = position; }
const std::optional<Vec2d>& get_popup_menu_position() const { return m_popup_menu_positon; }
void clear_popup_menu_position() { m_popup_menu_positon.reset(); }

void set_tooltip(const std::string& tooltip);

// the following methods add a snapshot to the undo/redo stack, unless the given string is empty
Expand Down
135 changes: 112 additions & 23 deletions src/slic3r/GUI/GUI_Factories.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
///|/ Copyright (c) Prusa Research 2021 - 2023 Enrico Turri @enricoturri1966, Lukáš Matěna @lukasmatena, Oleksandra Iushchenko @YuSanka, Pavel Mikuš @Godrak, Tomáš Mészáros @tamasmeszaros, Filip Sykala @Jony01, Vojtěch Bubník @bubnikv
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#include "libslic3r/libslic3r.h"
#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Model.hpp"
Expand All @@ -15,6 +19,7 @@
#include "format.hpp"
//BBS: add partplate related logic
#include "PartPlate.hpp"
#include "Gizmos/GLGizmoEmboss.hpp"

#include <boost/algorithm/string.hpp>
#include "slic3r/Utils/FixModelByWin10.hpp"
Expand Down Expand Up @@ -274,24 +279,22 @@ wxBitmap SettingsFactory::get_category_bitmap(const std::string& category_name,
//-------------------------------------

// Note: id accords to type of the sub-object (adding volume), so sequence of the menu items is important
#ifdef __WINDOWS__
const std::vector<std::pair<std::string, std::string>> MenuFactory::ADD_VOLUME_MENU_ITEMS = {
static const constexpr std::array<std::pair<const char *, const char *>, 5> ADD_VOLUME_MENU_ITEMS = {{
// menu_item Name menu_item bitmap name
{L("Add part"), "menu_add_part" }, // ~ModelVolumeType::MODEL_PART
{L("Add negative part"), "menu_add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
{L("Add modifier"), "menu_add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
{L("Add support blocker"), "menu_support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER
{L("Add support enforcer"), "menu_support_enforcer"} // ~ModelVolumeType::SUPPORT_ENFORCER
};
#else
const std::vector<std::pair<std::string, std::string>> MenuFactory::ADD_VOLUME_MENU_ITEMS = {
{L("Add part"), "menu_add_part" }, // ~ModelVolumeType::MODEL_PART
{L("Add negative part"), "menu_add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
{L("Add modifier"), "menu_add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
{L("Add support blocker"), "menu_support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER
{L("Add support enforcer"), "menu_support_enforcer"} // ~ModelVolumeType::SUPPORT_ENFORCER
};
{L("Add support enforcer"), "menu_support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER
}};

#endif
// Note: id accords to type of the sub-object (adding volume), so sequence of the menu items is important
static const constexpr std::array<std::pair<const char *, const char *>, 3> TEXT_VOLUME_ICONS {{
// menu_item Name menu_item bitmap name
{L("Add text"), "add_text_part"}, // ~ModelVolumeType::MODEL_PART
{L("Add negative text"), "add_text_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
{L("Add text modifier"), "add_text_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
}};

static Plater* plater()
{
Expand Down Expand Up @@ -429,14 +432,21 @@ std::vector<wxBitmap> MenuFactory::get_volume_bitmaps()
{
std::vector<wxBitmap> volume_bmps;
volume_bmps.reserve(ADD_VOLUME_MENU_ITEMS.size());
for (auto item : ADD_VOLUME_MENU_ITEMS){
if(!item.second.empty()){
volume_bmps.push_back(create_scaled_bitmap(item.second));
}
for (const auto& item : ADD_VOLUME_MENU_ITEMS){
volume_bmps.push_back(create_scaled_bitmap(item.second));
}
return volume_bmps;
}

std::vector<wxBitmap> MenuFactory::get_text_volume_bitmaps()
{
std::vector<wxBitmap> volume_bmps;
volume_bmps.reserve(TEXT_VOLUME_ICONS.size());
for (const auto& item : TEXT_VOLUME_ICONS)
volume_bmps.push_back(create_scaled_bitmap(item.second));
return volume_bmps;
}

void MenuFactory::append_menu_item_set_visible(wxMenu* menu)
{
bool has_one_shown = false;
Expand Down Expand Up @@ -496,6 +506,9 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty
},
"", menu);
}

append_menu_item_add_text(sub_menu, type);

sub_menu->AppendSeparator();
for (auto &item : {L("Cube"), L("Cylinder"), L("Sphere"), L("Cone")}) {
append_menu_item(
Expand All @@ -509,13 +522,65 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty
return sub_menu;
}

static void append_menu_itemm_add_(const wxString& name, GLGizmosManager::EType gizmo_type, wxMenu *menu, ModelVolumeType type, bool is_submenu_item) {
auto add_ = [type, gizmo_type](const wxCommandEvent & /*unnamed*/) {
const GLCanvas3D *canvas = plater()->canvas3D();
const GLGizmosManager &mng = canvas->get_gizmos_manager();
GLGizmoBase *gizmo_base = mng.get_gizmo(gizmo_type);

ModelVolumeType volume_type = type;
// no selected object means create new object
if (volume_type == ModelVolumeType::INVALID)
volume_type = ModelVolumeType::MODEL_PART;

auto screen_position = canvas->get_popup_menu_position();
if (gizmo_type == GLGizmosManager::Emboss) {
auto emboss = dynamic_cast<GLGizmoEmboss *>(gizmo_base);
assert(emboss != nullptr);
if (emboss == nullptr) return;
if (screen_position.has_value()) {
emboss->create_volume(volume_type, *screen_position);
} else {
emboss->create_volume(volume_type);
}
} /*else if (gizmo_type == GLGizmosManager::Svg) {
auto svg = dynamic_cast<GLGizmoSVG *>(gizmo_base);
assert(svg != nullptr);
if (svg == nullptr) return;
if (screen_position.has_value()) {
svg->create_volume(volume_type, *screen_position);
} else {
svg->create_volume(volume_type);
}
}*/
};

if (type == ModelVolumeType::MODEL_PART || type == ModelVolumeType::NEGATIVE_VOLUME || type == ModelVolumeType::PARAMETER_MODIFIER ||
type == ModelVolumeType::INVALID // cannot use gizmo without selected object
) {
wxString item_name = wxString(is_submenu_item ? "" : _(ADD_VOLUME_MENU_ITEMS[int(type)].first) + ": ") + name;
menu->AppendSeparator();
const std::string icon_name = is_submenu_item ? "" : ADD_VOLUME_MENU_ITEMS[int(type)].second;
append_menu_item(menu, wxID_ANY, item_name, "", add_, icon_name, menu);
}
}

void MenuFactory::append_menu_item_add_text(wxMenu* menu, ModelVolumeType type, bool is_submenu_item/* = true*/){
append_menu_itemm_add_(_L("Text"), GLGizmosManager::Emboss, menu, type, is_submenu_item);
}

void MenuFactory::append_menu_items_add_volume(wxMenu* menu)
{
// Update "add" items(delete old & create new) settings popupmenu
for (auto& item : ADD_VOLUME_MENU_ITEMS) {
const auto settings_id = menu->FindItem(_(item.first));
if (settings_id != wxNOT_FOUND)
menu->Destroy(settings_id);
const wxString item_name = _(item.first);
int item_id = menu->FindItem(item_name);
if (item_id != wxNOT_FOUND)
menu->Destroy(item_id);

item_id = menu->FindItem(item_name + ": " + _L("Text"));
if (item_id != wxNOT_FOUND)
menu->Destroy(item_id);
}

for (size_t type = 0; type < ADD_VOLUME_MENU_ITEMS.size(); type++)
Expand Down Expand Up @@ -989,15 +1054,15 @@ void MenuFactory::append_menu_item_edit_text(wxMenu *menu)
return false;
return volume->is_text();
};
/*

if (menu != &m_text_part_menu) {
const int menu_item_id = menu->FindItem(name);
if (menu_item_id != wxNOT_FOUND)
menu->Destroy(menu_item_id);
if (!can_edit_text())
return;
}
*/

wxString description = _L("Ability to change text, font, size, ...");
std::string icon = "cog";
auto open_emboss = [](const wxCommandEvent &) {
Expand Down Expand Up @@ -1192,6 +1257,20 @@ void MenuFactory::create_part_menu()
append_menu_item_per_object_settings(&m_part_menu);
}

void MenuFactory::create_text_part_menu()
{
wxMenu* menu = &m_text_part_menu;

append_menu_item_edit_text(menu);
append_menu_item_delete(menu);
append_menu_item_fix_through_netfabb(menu);
append_menu_item_simplify(menu);
append_menu_items_mirror(menu);
menu->AppendSeparator();
append_menu_item_per_object_settings(menu);
append_menu_item_change_type(menu);
}

void MenuFactory::create_bbl_part_menu()
{
wxMenu* menu = &m_part_menu;
Expand Down Expand Up @@ -1318,7 +1397,7 @@ void MenuFactory::init(wxWindow* parent)
//create_object_menu();
create_sla_object_menu();
//create_part_menu();

create_text_part_menu();
create_extra_object_menu();
create_bbl_part_menu();
create_bbl_assemble_object_menu();
Expand Down Expand Up @@ -1347,6 +1426,7 @@ wxMenu* MenuFactory::object_menu()
append_menu_items_convert_unit(&m_object_menu);
append_menu_items_flush_options(&m_object_menu);
append_menu_item_invalidate_cut_info(&m_object_menu);
append_menu_item_edit_text(&m_object_menu);
append_menu_item_change_filament(&m_object_menu);
return &m_object_menu;
}
Expand All @@ -1356,6 +1436,7 @@ wxMenu* MenuFactory::sla_object_menu()
append_menu_items_convert_unit(&m_sla_object_menu);
append_menu_item_settings(&m_sla_object_menu);
//update_menu_items_instance_manipulation(mtObjectSLA);
append_menu_item_edit_text(&m_sla_object_menu);

return &m_sla_object_menu;
}
Expand All @@ -1368,6 +1449,14 @@ wxMenu* MenuFactory::part_menu()
return &m_part_menu;
}

wxMenu* MenuFactory::text_part_menu()
{
append_menu_item_change_filament(&m_text_part_menu);
append_menu_item_per_object_settings(&m_text_part_menu);

return &m_text_part_menu;
}

wxMenu* MenuFactory::instance_menu()
{
return &m_instance_menu;
Expand Down
12 changes: 10 additions & 2 deletions src/slic3r/GUI/GUI_Factories.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
///|/ Copyright (c) Prusa Research 2021 - 2022 Oleksandra Iushchenko @YuSanka, Tomáš Mészáros @tamasmeszaros, Lukáš Matěna @lukasmatena, Pavel Mikuš @Godrak, Filip Sykala @Jony01, Vojtěch Bubník @bubnikv
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#ifndef slic3r_GUI_Factories_hpp_
#define slic3r_GUI_Factories_hpp_

Expand Down Expand Up @@ -47,8 +51,8 @@ struct SettingsFactory
class MenuFactory
{
public:
static const std::vector<std::pair<std::string, std::string>> ADD_VOLUME_MENU_ITEMS;
static std::vector<wxBitmap> get_volume_bitmaps();
static std::vector<wxBitmap> get_text_volume_bitmaps();

MenuFactory();
~MenuFactory() = default;
Expand All @@ -66,6 +70,7 @@ class MenuFactory
wxMenu* object_menu();
wxMenu* sla_object_menu();
wxMenu* part_menu();
wxMenu* text_part_menu();
wxMenu* instance_menu();
wxMenu* layer_menu();
wxMenu* multi_selection_menu();
Expand All @@ -86,6 +91,7 @@ class MenuFactory

MenuWithSeparators m_object_menu;
MenuWithSeparators m_part_menu;
MenuWithSeparators m_text_part_menu;
MenuWithSeparators m_sla_object_menu;
MenuWithSeparators m_default_menu;
MenuWithSeparators m_instance_menu;
Expand All @@ -105,6 +111,7 @@ class MenuFactory
void create_object_menu();
void create_sla_object_menu();
void create_part_menu();
void create_text_part_menu();
//BBS: add part plate related logic
void create_plate_menu();
//BBS: add bbl object menu
Expand All @@ -114,6 +121,7 @@ class MenuFactory
void create_bbl_assemble_part_menu();

wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type);
void append_menu_item_add_text(wxMenu* menu, ModelVolumeType type, bool is_submenu_item = true);
void append_menu_items_add_volume(wxMenu* menu);
wxMenuItem* append_menu_item_layers_editing(wxMenu* menu);
wxMenuItem* append_menu_item_settings(wxMenu* menu);
Expand All @@ -129,7 +137,6 @@ class MenuFactory
void append_menu_item_change_extruder(wxMenu* menu);
void append_menu_item_set_visible(wxMenu* menu);
void append_menu_item_delete(wxMenu* menu);
void append_menu_item_edit_text(wxMenu *menu);
void append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu);
void append_menu_items_convert_unit(wxMenu* menu); // Add "Conver/Revert..." menu items (from/to inches/meters) after "Reload From Disk"
void append_menu_items_flush_options(wxMenu* menu);
Expand All @@ -138,6 +145,7 @@ class MenuFactory
void append_menu_item_merge_parts_to_single_part(wxMenu *menu);
void append_menu_items_mirror(wxMenu *menu);
void append_menu_item_invalidate_cut_info(wxMenu *menu);
void append_menu_item_edit_text(wxMenu *menu);

//void append_menu_items_instance_manipulation(wxMenu *menu);
//void update_menu_items_instance_manipulation(MenuType type);
Expand Down
22 changes: 17 additions & 5 deletions src/slic3r/GUI/GUI_ObjectList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1289,11 +1289,20 @@ void ObjectList::show_context_menu(const bool evt_context_menu)
const ItemType type = m_objects_model->GetItemType(item);
if (!(type & (itPlate | itObject | itVolume | itInstance)))
return;
if (type & itVolume) {
int obj_idx, vol_idx;
get_selected_item_indexes(obj_idx, vol_idx, item);
if (obj_idx < 0 || vol_idx < 0)
return;
const ModelVolume *volume = object(obj_idx)->volumes[vol_idx];

menu = type & itPlate ? plater->plate_menu() :
type & itInstance ? plater->instance_menu() :
type & itVolume ? plater->part_menu() :
printer_technology() == ptFFF ? plater->object_menu() : plater->sla_object_menu();
menu = volume->is_text() ? plater->text_part_menu() :
plater->part_menu();
}
else
menu = type & itPlate ? plater->plate_menu() :
type & itInstance ? plater->instance_menu() :
printer_technology() == ptFFF ? plater->object_menu() : plater->sla_object_menu();
plater->SetPlateIndexByRightMenuInLeftUI(-1);
if (type & itPlate) {
int plate_idx = -1;
Expand Down Expand Up @@ -2523,7 +2532,8 @@ void ObjectList::split()
for (const ModelVolume* volume : model_object->volumes) {
const wxDataViewItem& vol_item = m_objects_model->AddVolumeChild(parent, from_u8(volume->name),
volume->type(),// is_modifier() ? ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART,
get_warning_icon_name(volume->mesh().stats()),
volume->is_text(),
get_warning_icon_name(volume->mesh().stats()),
volume->config.has("extruder") ? volume->config.extruder() : 0,
false);
// add settings to the part, if it has those
Expand Down Expand Up @@ -3679,6 +3689,7 @@ wxDataViewItemArray ObjectList::add_volumes_to_object_in_list(size_t obj_idx, st
object_item,
from_u8(volume->name),
volume->type(),
volume->is_text(),
get_warning_icon_name(volume->mesh().stats()),
volume->config.has("extruder") ? volume->config.extruder() : 0,
false);
Expand Down Expand Up @@ -5691,6 +5702,7 @@ wxDataViewItemArray ObjectList::reorder_volumes_and_get_selection(int obj_idx, s
for (const ModelVolume* volume : object->volumes) {
wxDataViewItem vol_item = m_objects_model->AddVolumeChild(object_item, from_u8(volume->name),
volume->type(),
volume->is_text(),
get_warning_icon_name(volume->mesh().stats()),
volume->config.has("extruder") ? volume->config.extruder() : 0,
false);
Expand Down
Loading

0 comments on commit 84d7aaa

Please sign in to comment.