NEW:add "svg" in right menu

jira:none
most of code is from PrusaSlicer and OrcaSlicer,thanks for  Filip Sykala - NTB T15p(PrusaSlicer) and Noisyfox(OrcaSlicer)
 Port Emboss & SVG gizmo from PrusaSlicer (#2819)
* Rework UI jobs to make them more understandable and flexible.

Change-Id: I06bf1e4db0068b8b452083a1624dec2620e5d336
This commit is contained in:
zhou.xu 2024-09-10 20:01:42 +08:00 committed by Lane.Wei
parent 811e257936
commit 2a7a3f9960
7 changed files with 137 additions and 28 deletions

View File

@ -5464,6 +5464,14 @@ bool GLCanvas3D::is_object_sinking(int object_idx) const
return false;
}
void GLCanvas3D::apply_retina_scale(Vec2d &screen_coordinate) const
{
#if ENABLE_RETINA_GL
double scale = static_cast<double>(m_retina_helper->get_scale_factor());
screen_coordinate *= scale;
#endif // ENABLE_RETINA_GL}
}
bool GLCanvas3D::_is_shown_on_screen() const
{
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;

View File

@ -949,6 +949,12 @@ public:
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
@ -1080,7 +1086,7 @@ public:
void reset_old_size() { m_old_size = { 0, 0 }; }
bool is_object_sinking(int object_idx) const;
void apply_retina_scale(Vec2d &screen_coordinate) const;
void _perform_layer_editing_action(wxMouseEvent* evt = nullptr);
// Convert the screen space coordinate to an object space coordinate.

View File

@ -16,6 +16,8 @@
//BBS: add partplate related logic
#include "PartPlate.hpp"
#include "Gizmos/GLGizmoSVG.hpp"
#include <boost/algorithm/string.hpp>
#include "slic3r/Utils/FixModelByWin10.hpp"
#include "ParamsPanel.hpp"
@ -436,10 +438,8 @@ 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;
}
@ -486,6 +486,7 @@ void MenuFactory::append_menu_item_delete(wxMenu* menu)
#endif
}
void MenuFactory::append_menu_item_edit_text(wxMenu *menu)
{
#ifdef __WINDOWS__
@ -553,10 +554,60 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty
sub_menu, wxID_ANY, _(item), "", [type, item](wxCommandEvent &) { obj_list()->load_generic_subobject(item, type); }, "", menu);
}
}
append_menu_item_add_svg(sub_menu, type);
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) {//todo
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();
auto def_icon_name = (gizmo_type == GLGizmosManager::Svg) ? "menu_obj_svg" : "menu_obj_text";
const std::string icon_name = is_submenu_item ? def_icon_name : 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_svg(wxMenu *menu, ModelVolumeType type, bool is_submenu_item /* = true*/)
{
append_menu_itemm_add_(_L("SVG"), GLGizmosManager::Svg, menu, type, is_submenu_item);
}
void MenuFactory::append_menu_items_add_volume(wxMenu* menu)
{
// Update "add" items(delete old & create new) settings popupmenu

View File

@ -128,6 +128,7 @@ private:
void create_bbl_assemble_part_menu();
wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type);
void append_menu_item_add_svg(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);

View File

@ -424,6 +424,24 @@ bool reset_button(const IconManager::VIcons &icons)
return draw_clickable(icons, IconType::reset_value);
}
bool GLGizmoSVG::create_volume(ModelVolumeType volume_type)
{
Emboss::CreateVolumeParams input = create_input(m_parent, volume_type);
Emboss::DataBasePtr base = create_emboss_data_base(m_job_cancel, volume_type);
if (!base)
return false; // Uninterpretable svg
return start_create_volume_without_position(input, std::move(base));
}
bool GLGizmoSVG::create_volume(ModelVolumeType volume_type, const Vec2d &mouse_pos)
{
Emboss::CreateVolumeParams input = create_input(m_parent, volume_type);
Emboss::DataBasePtr base = create_emboss_data_base(m_job_cancel, volume_type);
if (!base)
return false; // Uninterpretable svg
return start_create_volume(input, std::move(base), mouse_pos);
}
bool GLGizmoSVG::create_volume(std::string_view svg_file, const Vec2d &mouse_pos, ModelVolumeType volume_type)
{//drag file//drag svg_file
wxBusyCursor wait;

View File

@ -22,7 +22,7 @@ class Worker;
enum class SLAGizmoEventType : unsigned char;
class GLGizmoSVG : public GLGizmoBase
{
Emboss::DataBasePtr create_emboss_data_base(std::shared_ptr<std::atomic<bool>> &cancel, ModelVolumeType volume_type, std::string_view filepath);
Emboss::DataBasePtr create_emboss_data_base(std::shared_ptr<std::atomic<bool>> &cancel, ModelVolumeType volume_type, std::string_view filepath = "");
Emboss::CreateVolumeParams create_input(GLCanvas3D &canvas, ModelVolumeType volume_type);
@ -36,6 +36,14 @@ public:
void on_enable_grabber(unsigned int id) override;
void on_disable_grabber(unsigned int id) override;
/// <summary>
/// Create new text without given position
/// </summary>
/// <param name="volume_type">Object part / Negative volume / Modifier</param>
/// <returns>True on succesfull start creation otherwise False</returns>
bool create_volume(ModelVolumeType volume_type); // first open file dialog //by rigth menu
bool create_volume(ModelVolumeType volume_type, const Vec2d &mouse_pos); // first open file dialog //by rigth menu
bool create_volume(std::string_view svg_file, const Vec2d &mouse_pos, ModelVolumeType volume_type = ModelVolumeType::MODEL_PART);
/// <summary>
/// Check whether volume is object containing only emboss volume

View File

@ -2569,6 +2569,7 @@ struct Plater::priv
void on_add_custom_filament(ColorEvent &);
void on_object_select(SimpleEvent&);
void show_right_click_menu(Vec2d mouse_position, wxMenu *menu);
void on_plate_name_change(SimpleEvent &);
void on_right_click(RBtnEvent&);
//BBS: add model repair
@ -7319,6 +7320,41 @@ void Plater::priv::on_change_color_mode(SimpleEvent& evt) {
if (m_send_to_sdcard_dlg) m_send_to_sdcard_dlg->on_change_color_mode();
}
static void get_position(wxWindowBase *child, wxWindowBase *until_parent, int &x, int &y)
{
int res_x = 0, res_y = 0;
while (child != until_parent && child != nullptr) {
int _x, _y;
child->GetPosition(&_x, &_y);
res_x += _x;
res_y += _y;
child = child->GetParent();
}
x = res_x;
y = res_y;
}
void Plater::priv::show_right_click_menu(Vec2d mouse_position, wxMenu *menu)
{
// BBS: GUI refactor: move sidebar to the left
int x, y;
get_position(current_panel, wxGetApp().mainframe, x, y);
wxPoint position(static_cast<int>(mouse_position.x() + x), static_cast<int>(mouse_position.y() + y));
#ifdef __linux__
// For some reason on Linux the menu isn't displayed if position is
// specified (even though the position is sane).
position = wxDefaultPosition;
#endif
GLCanvas3D &canvas = *q->canvas3D();
canvas.apply_retina_scale(mouse_position);
canvas.set_popup_menu_position(mouse_position);
q->PopupMenu(menu, position);
canvas.clear_popup_menu_position();
}
void Plater::priv::on_right_click(RBtnEvent& evt)
{
int obj_idx = get_selected_object_idx();
@ -7380,17 +7416,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt)
}
if (q != nullptr && menu) {
#ifdef __linux__
// For some reason on Linux the menu isn't displayed if position is specified
// (even though the position is sane).
q->PopupMenu(menu);
#else
//BBS: GUI refactor: move sidebar to the left
int x, y;
current_panel->GetPosition(&x, &y);
q->PopupMenu(menu, (int)evt.data.first.x() + x, (int)evt.data.first.y());
//q->PopupMenu(menu);
#endif
show_right_click_menu(evt.data.first, menu);
}
}
@ -7398,16 +7424,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt)
void Plater::priv::on_plate_right_click(RBtnPlateEvent& evt)
{
wxMenu* menu = menus.plate_menu();
#ifdef __linux__
q->PopupMenu(menu);
#else
//BBS: GUI refactor: move sidebar to the left
int x, y;
current_panel->GetPosition(&x, &y);
q->PopupMenu(menu, (int)evt.data.first.x() + x, (int)evt.data.first.y());
//q->PopupMenu(menu);
#endif
show_right_click_menu(evt.data.first, menu);
}
void Plater::priv::on_update_geometry(Vec3dsEvent<2>&)