From 508ae3ba5528e778967cd372ad8727d659b7df48 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Sun, 29 Apr 2018 22:50:06 -0500 Subject: [PATCH] further fleshing out of 2d plater --- src/GUI/Plater/Plate2D.cpp | 92 ++++++++++++++++++++++++++++++++++++++ src/GUI/Plater/Plate2D.hpp | 38 +++++++++++++++- 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/src/GUI/Plater/Plate2D.cpp b/src/GUI/Plater/Plate2D.cpp index 13ebb43f6..e9a906c22 100644 --- a/src/GUI/Plater/Plate2D.cpp +++ b/src/GUI/Plater/Plate2D.cpp @@ -1,7 +1,12 @@ #include "Plater/Plate2D.hpp" + +// libslic3r includes +#include "Geometry.hpp" #include "Log.hpp" +// wx includes #include +#include namespace Slic3r { namespace GUI { @@ -15,6 +20,8 @@ Plate2D::Plate2D(wxWindow* parent, const wxSize& size, std::vectorBind(wxEVT_ERASE_BACKGROUND, [=](wxEraseEvent& e){ }); } + this->Bind(wxEVT_SIZE, [=](wxSizeEvent &e) { this->update_bed_size(); this->Refresh(); }); + // Bind the varying mouse events // Set the brushes @@ -22,6 +29,36 @@ Plate2D::Plate2D(wxWindow* parent, const wxSize& size, std::vectorSetFocus(); + + auto dc {new wxAutoBufferedPaintDC(this)}; + const auto& size = this->GetSize(); + + + if (this->user_drawn_background) { + // On all systems the AutoBufferedPaintDC() achieves double buffering. + // On MacOS the background is erased, on Windows the background is not erased + // and on Linux/GTK the background is erased to gray color. + // Fill DC with the background on Windows & Linux/GTK. + const auto& brush_background {wxBrush(this->settings->color->BACKGROUND255(), wxBRUSHSTYLE_SOLID)}; + const auto& pen_background {wxPen(this->settings->color->BACKGROUND255(), 1, wxPENSTYLE_SOLID)}; + dc->SetPen(pen_background); + dc->SetBrush(brush_background); + const auto& rect {this->GetUpdateRegion().GetBox()}; + dc->DrawRectangle(rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight()); + } + + // Draw bed + { + dc->SetPen(this->print_center_pen); + dc->SetBrush(this->bed_brush); + + dc->DrawPolygon(scaled_points_to_pixel(this->bed_polygon, true), 0, 0); + } + + } void Plate2D::mouse_drag(wxMouseEvent& e) { @@ -67,4 +104,59 @@ void Plate2D::set_colors() { } +void Plate2D::nudge_key(wxKeyEvent& e) { + const auto key = e.GetKeyCode(); + + switch( key ) { + case WXK_LEFT: + this->nudge(MoveDirection::Left); + case WXK_RIGHT: + this->nudge(MoveDirection::Right); + case WXK_DOWN: + this->nudge(MoveDirection::Down); + case WXK_UP: + this->nudge(MoveDirection::Up); + default: + break; // do nothing + } + +} + +void Plate2D::nudge(MoveDirection dir) { + if (this->selected_instance < this->objects.size()) { + auto i = 0U; + for (auto& obj : this->objects) { + if (obj.selected()) { + if (obj.selected_instance != -1) { + } + } + i++; + } + } + if (selected_instance >= this->objects.size()) { + Slic3r::Log::warn(LogChannel, L"Nudge failed because there is no selected instance."); + return; // Abort + } +} + +void Plate2D::update_bed_size() { + const auto& canvas_size {this->GetSize()}; + const auto& canvas_w {canvas_size.GetWidth()}; + const auto& canvas_h {canvas_size.GetHeight()}; + if (canvas_w == 0) return; // Abort early if we haven't drawn canvas yet. + + this->bed_polygon = Slic3r::Polygon(); + const auto& polygon = bed_polygon; + + const auto& bb = bed_polygon.bounding_box(); + const auto& size = bb.size(); + + this->scaling_factor = std::min(static_cast(canvas_w) / unscale(size.x), + static_cast(canvas_h) / unscale(size.y)); + + assert(this->scaling_factor != 0); + + +} + } } // Namespace Slic3r::GUI diff --git a/src/GUI/Plater/Plate2D.hpp b/src/GUI/Plater/Plate2D.hpp index 07ae3451a..553400a44 100644 --- a/src/GUI/Plater/Plate2D.hpp +++ b/src/GUI/Plater/Plate2D.hpp @@ -6,6 +6,7 @@ #endif #include +#include #include "Plater.hpp" #include "ColorScheme.hpp" #include "Settings.hpp" @@ -18,9 +19,16 @@ namespace Slic3r { namespace GUI { +enum class MoveDirection { + Up, Down, Left, Right +}; + class Plate2D : public wxPanel { public: Plate2D(wxWindow* parent, const wxSize& size, std::vector& _objects, std::shared_ptr _model, std::shared_ptr _config, std::shared_ptr _settings); + + +// std::function<> on_select_object {}; private: std::vector& objects; std::shared_ptr model; @@ -42,7 +50,7 @@ private: wxPen dark_pen {}; bool user_drawn_background {(the_os == OS::Mac ? false : true)}; - Plater2DObject selected_instance; + size_t selected_instance; /// Handle mouse-move events void mouse_drag(wxMouseEvent& e); @@ -50,10 +58,36 @@ private: /// Handle repaint events void repaint(wxPaintEvent& e); + void nudge_key(wxKeyEvent& e); + + void nudge(MoveDirection dir); + /// Set/Update all of the colors used by the various brushes in the panel. void set_colors(); - + + /// Convert a scale point array to a pixel polygon suitable for DrawPolygon + std::vector scaled_points_to_pixel(std::vector points, bool unscale); + + // For a specific point, unscaled it + wxPoint unscaled_point_to_pixel(const wxPoint& in) { + const auto& canvas_height {this->GetSize().GetHeight()}; + const auto& zero = this->bed_origin; + return wxPoint(in.x * this->scaling_factor + zero.x, + in.x * this->scaling_factor + (zero.y - canvas_height)); + } + + /// Read print bed size from config. + void update_bed_size(); + const std::string LogChannel {"GUI_2D"}; + + wxPoint bed_origin {}; + Slic3r::Polygon bed_polygon {}; + + /// How much to scale the points to fit in the draw bounding box area. + /// Expressed as pixel / mm + double scaling_factor {1.0}; + }; } } // Namespace Slic3r::GUI