mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	+ Added "proces_enter" mode for TextCtrl (The control will generate the event wxEVT_TEXT_ENTER)
		
			
				
	
	
		
			278 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef slic3r_OptionsGroup_hpp_
 | 
						|
#define slic3r_OptionsGroup_hpp_
 | 
						|
 | 
						|
#include <wx/wx.h>
 | 
						|
#include <wx/stattext.h>
 | 
						|
#include <wx/settings.h>
 | 
						|
//#include <wx/window.h>
 | 
						|
 | 
						|
#include <map>
 | 
						|
#include <functional>
 | 
						|
 | 
						|
#include "libslic3r/Config.hpp"
 | 
						|
#include "libslic3r/PrintConfig.hpp"
 | 
						|
#include "libslic3r/libslic3r.h"
 | 
						|
 | 
						|
#include "Field.hpp"
 | 
						|
#include "GUI_App.hpp"
 | 
						|
 | 
						|
// Translate the ifdef 
 | 
						|
#ifdef __WXOSX__
 | 
						|
    #define wxOSX true
 | 
						|
#else
 | 
						|
    #define wxOSX false
 | 
						|
#endif
 | 
						|
 | 
						|
#define BORDER(a, b) ((wxOSX ? a : b))
 | 
						|
 | 
						|
namespace Slic3r { namespace GUI {
 | 
						|
 | 
						|
/// Widget type describes a function object that returns a wxWindow (our widget) and accepts a wxWidget (parent window).
 | 
						|
using widget_t = std::function<wxSizer*(wxWindow*)>;//!std::function<wxWindow*(wxWindow*)>;
 | 
						|
 | 
						|
//auto default_label_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); //GetSystemColour
 | 
						|
//auto modified_label_clr = *new wxColour(254, 189, 101);
 | 
						|
 | 
						|
/// Wraps a ConfigOptionDef and adds function object for creating a side_widget.
 | 
						|
struct Option {
 | 
						|
	ConfigOptionDef			opt { ConfigOptionDef() };
 | 
						|
	t_config_option_key		opt_id;//! {""};
 | 
						|
    widget_t				side_widget {nullptr};
 | 
						|
    bool					readonly {false};
 | 
						|
 | 
						|
	Option(const ConfigOptionDef& _opt, t_config_option_key id) :
 | 
						|
		opt(_opt), opt_id(id) {}
 | 
						|
};
 | 
						|
using t_option = std::unique_ptr<Option>;	//!
 | 
						|
 | 
						|
/// Represents option lines
 | 
						|
class Line {
 | 
						|
public:
 | 
						|
    wxString	label {wxString("")};
 | 
						|
    wxString	label_tooltip {wxString("")};
 | 
						|
    size_t		full_width {0}; 
 | 
						|
    wxSizer*	sizer {nullptr};
 | 
						|
    widget_t	widget {nullptr};
 | 
						|
    std::function<wxWindow*(wxWindow*)>	near_label_widget{ nullptr };
 | 
						|
 | 
						|
    void append_option(const Option& option) {
 | 
						|
        m_options.push_back(option);
 | 
						|
    }
 | 
						|
	void append_widget(const widget_t widget) {
 | 
						|
		m_extra_widgets.push_back(widget);
 | 
						|
    }
 | 
						|
	Line(wxString label, wxString tooltip) :
 | 
						|
		label(label), label_tooltip(tooltip) {}
 | 
						|
 | 
						|
    const std::vector<widget_t>&	get_extra_widgets() const {return m_extra_widgets;}
 | 
						|
    const std::vector<Option>&		get_options() const { return m_options; }
 | 
						|
 | 
						|
private:
 | 
						|
	std::vector<Option>		m_options;//! {std::vector<Option>()};
 | 
						|
    std::vector<widget_t>	m_extra_widgets;//! {std::vector<widget_t>()};
 | 
						|
};
 | 
						|
 | 
						|
using column_t = std::function<wxWindow*(wxWindow* parent, const Line&)>;//std::function<wxSizer*(const Line&)>;
 | 
						|
 | 
						|
using t_optionfield_map = std::map<t_config_option_key, t_field>;
 | 
						|
using t_opt_map = std::map< std::string, std::pair<std::string, int> >;
 | 
						|
 | 
						|
class OptionsGroup {
 | 
						|
	wxStaticBox*	stb;
 | 
						|
public:
 | 
						|
    const bool		staticbox {true};
 | 
						|
    const wxString	title {wxString("")};
 | 
						|
    size_t			label_width {200};
 | 
						|
    wxSizer*		sizer {nullptr};
 | 
						|
    column_t		extra_column {nullptr};
 | 
						|
    t_change		m_on_change {nullptr};
 | 
						|
	std::function<DynamicPrintConfig()>	m_get_initial_config{ nullptr };
 | 
						|
	std::function<DynamicPrintConfig()>	m_get_sys_config{ nullptr };
 | 
						|
	std::function<bool()>	have_sys_config{ nullptr };
 | 
						|
 | 
						|
    wxFont			sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
 | 
						|
    wxFont			label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
 | 
						|
	int				sidetext_width{ -1 };
 | 
						|
 | 
						|
    bool            process_enter { false };
 | 
						|
 | 
						|
    /// Returns a copy of the pointer of the parent wxWindow.
 | 
						|
    /// Accessor function is because users are not allowed to change the parent
 | 
						|
    /// but defining it as const means a lot of const_casts to deal with wx functions.
 | 
						|
    inline wxWindow* parent() const { 
 | 
						|
#ifdef __WXGTK__
 | 
						|
		return m_panel;
 | 
						|
#else
 | 
						|
		return m_parent;
 | 
						|
#endif /* __WXGTK__ */
 | 
						|
    }
 | 
						|
#ifdef __WXGTK__
 | 
						|
    wxWindow* get_parent() const {
 | 
						|
        return m_parent;
 | 
						|
    }
 | 
						|
#endif /* __WXGTK__ */
 | 
						|
 | 
						|
	void		append_line(const Line& line, wxStaticText** colored_Label = nullptr);
 | 
						|
    Line		create_single_option_line(const Option& option) const;
 | 
						|
    void		append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); }
 | 
						|
 | 
						|
    // return a non-owning pointer reference 
 | 
						|
    inline Field*	get_field(const t_config_option_key& id) const{
 | 
						|
							if (m_fields.find(id) == m_fields.end()) return nullptr;
 | 
						|
							return m_fields.at(id).get();
 | 
						|
    }
 | 
						|
	bool			set_value(const t_config_option_key& id, const boost::any& value, bool change_event = false) {
 | 
						|
							if (m_fields.find(id) == m_fields.end()) return false;
 | 
						|
							m_fields.at(id)->set_value(value, change_event);
 | 
						|
							return true;
 | 
						|
    }
 | 
						|
	boost::any		get_value(const t_config_option_key& id) {
 | 
						|
							boost::any out; 
 | 
						|
    						if (m_fields.find(id) == m_fields.end()) ;
 | 
						|
							else 
 | 
						|
								out = m_fields.at(id)->get_value();
 | 
						|
							return out;
 | 
						|
    }
 | 
						|
 | 
						|
	bool			set_side_text(const t_config_option_key& opt_key, const wxString& side_text) {
 | 
						|
							if (m_fields.find(opt_key) == m_fields.end()) return false;
 | 
						|
							auto st = m_fields.at(opt_key)->m_side_text;
 | 
						|
							if (!st) return false;
 | 
						|
							st->SetLabel(side_text);
 | 
						|
							return true;
 | 
						|
    }
 | 
						|
 | 
						|
	void			set_name(const wxString& new_name) {
 | 
						|
							stb->SetLabel(new_name);
 | 
						|
    }
 | 
						|
 | 
						|
	inline void		enable() { for (auto& field : m_fields) field.second->enable(); }
 | 
						|
    inline void		disable() { for (auto& field : m_fields) field.second->disable(); }
 | 
						|
	void			set_grid_vgap(int gap) { m_grid_sizer->SetVGap(gap); }
 | 
						|
 | 
						|
	void            set_show_modified_btns_val(bool show) {
 | 
						|
		                m_show_modified_btns = show;
 | 
						|
    }
 | 
						|
 | 
						|
    // The controls inside this option group will generate the event wxEVT_TEXT_ENTER
 | 
						|
    void            set_process_enter() { 
 | 
						|
                        process_enter = true;
 | 
						|
    }
 | 
						|
 | 
						|
	OptionsGroup(	wxWindow* _parent, const wxString& title, bool is_tab_opt = false, 
 | 
						|
					column_t extra_clmn = nullptr) :
 | 
						|
					m_parent(_parent), title(title), 
 | 
						|
                    m_show_modified_btns(is_tab_opt),
 | 
						|
					staticbox(title!=""), extra_column(extra_clmn) {
 | 
						|
        if (staticbox) {
 | 
						|
            stb = new wxStaticBox(_parent, wxID_ANY, title);
 | 
						|
            stb->SetFont(wxGetApp().bold_font());
 | 
						|
        }
 | 
						|
        sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL));
 | 
						|
        auto num_columns = 1U;
 | 
						|
        if (label_width != 0) num_columns++;
 | 
						|
        if (extra_column != nullptr) num_columns++;
 | 
						|
        m_grid_sizer = new wxFlexGridSizer(0, num_columns, 1,0);
 | 
						|
        static_cast<wxFlexGridSizer*>(m_grid_sizer)->SetFlexibleDirection(wxBOTH/*wxHORIZONTAL*/);
 | 
						|
        static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(label_width == 0 ? 0 : !extra_column ? 1 : 2 );
 | 
						|
#ifdef __WXGTK__
 | 
						|
        m_panel = new wxPanel( _parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
 | 
						|
        sizer->Fit(m_panel);
 | 
						|
        sizer->Add(m_panel, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5);
 | 
						|
#else
 | 
						|
        sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5);
 | 
						|
#endif /* __WXGTK__ */
 | 
						|
    }
 | 
						|
 | 
						|
    wxGridSizer*        get_grid_sizer() { return m_grid_sizer; }
 | 
						|
 | 
						|
protected:
 | 
						|
	std::map<t_config_option_key, Option>	m_options;
 | 
						|
    wxWindow*				m_parent {nullptr};
 | 
						|
    std::vector<ConfigOptionMode>           m_options_mode;
 | 
						|
 | 
						|
    /// Field list, contains unique_ptrs of the derived type.
 | 
						|
    /// using types that need to know what it is beyond the public interface 
 | 
						|
    /// need to cast based on the related ConfigOptionDef.
 | 
						|
    t_optionfield_map		m_fields;
 | 
						|
    bool					m_disabled {false};
 | 
						|
    wxGridSizer*			m_grid_sizer {nullptr};
 | 
						|
	// "true" if option is created in preset tabs
 | 
						|
	bool					m_show_modified_btns{ false };
 | 
						|
 | 
						|
	// This panel is needed for correct showing of the ToolTips for Button, StaticText and CheckBox
 | 
						|
	// Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel 
 | 
						|
	// inside it before you insert the other controls.
 | 
						|
#ifdef __WXGTK__
 | 
						|
	wxPanel*				m_panel {nullptr};
 | 
						|
#endif /* __WXGTK__ */
 | 
						|
 | 
						|
    /// Generate a wxSizer or wxWindow from a configuration option
 | 
						|
    /// Precondition: opt resolves to a known ConfigOption
 | 
						|
    /// Postcondition: fields contains a wx gui object.
 | 
						|
	const t_field&		build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label = nullptr);
 | 
						|
	const t_field&		build_field(const t_config_option_key& id, wxStaticText* label = nullptr);
 | 
						|
	const t_field&		build_field(const Option& opt, wxStaticText* label = nullptr);
 | 
						|
	void				add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field);
 | 
						|
 | 
						|
    virtual void		on_kill_focus () {};
 | 
						|
	virtual void		on_change_OG(const t_config_option_key& opt_id, const boost::any& value);
 | 
						|
	virtual void		back_to_initial_value(const std::string& opt_key) {}
 | 
						|
	virtual void		back_to_sys_value(const std::string& opt_key) {}
 | 
						|
};
 | 
						|
 | 
						|
class ConfigOptionsGroup: public OptionsGroup {
 | 
						|
public:
 | 
						|
	ConfigOptionsGroup(	wxWindow* parent, const wxString& title, DynamicPrintConfig* _config = nullptr, 
 | 
						|
						bool is_tab_opt = false, column_t extra_clmn = nullptr) :
 | 
						|
		OptionsGroup(parent, title, is_tab_opt, extra_clmn), m_config(_config) {}
 | 
						|
 | 
						|
    /// reference to libslic3r config, non-owning pointer (?).
 | 
						|
    DynamicPrintConfig*		m_config {nullptr};
 | 
						|
    bool					m_full_labels {0};
 | 
						|
	t_opt_map				m_opt_map;
 | 
						|
 | 
						|
    void        set_config(DynamicPrintConfig* config) { m_config = config; }
 | 
						|
	Option		get_option(const std::string& opt_key, int opt_index = -1);
 | 
						|
	Line		create_single_option_line(const std::string& title, int idx = -1) /*const*/{
 | 
						|
		Option option = get_option(title, idx);
 | 
						|
		return OptionsGroup::create_single_option_line(option);
 | 
						|
	}
 | 
						|
	void		append_single_option_line(const Option& option)	{
 | 
						|
		OptionsGroup::append_single_option_line(option);
 | 
						|
	}
 | 
						|
	void		append_single_option_line(const std::string title, int idx = -1)
 | 
						|
	{
 | 
						|
		Option option = get_option(title, idx);
 | 
						|
		append_single_option_line(option);		
 | 
						|
	}
 | 
						|
 | 
						|
	void		on_change_OG(const t_config_option_key& opt_id, const boost::any& value) override;
 | 
						|
	void		back_to_initial_value(const std::string& opt_key) override;
 | 
						|
	void		back_to_sys_value(const std::string& opt_key) override;
 | 
						|
	void		back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key);
 | 
						|
	void		on_kill_focus() override{ reload_config();}
 | 
						|
	void		reload_config();
 | 
						|
    // return value shows visibility : false => all options are hidden
 | 
						|
    void        Hide();
 | 
						|
    void        Show(const bool show);
 | 
						|
    bool        update_visibility(ConfigOptionMode mode);
 | 
						|
	boost::any	config_value(const std::string& opt_key, int opt_index, bool deserialize);
 | 
						|
	// return option value from config 
 | 
						|
	boost::any	get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1);
 | 
						|
	Field*		get_fieldc(const t_config_option_key& opt_key, int opt_index);
 | 
						|
};
 | 
						|
 | 
						|
//  Static text shown among the options.
 | 
						|
class ogStaticText :public wxStaticText{
 | 
						|
public:
 | 
						|
	ogStaticText() {}
 | 
						|
	ogStaticText(wxWindow* parent, const char *text) : wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize) {}
 | 
						|
	~ogStaticText() {}
 | 
						|
 | 
						|
	void		SetText(const wxString& value, bool wrap = true);
 | 
						|
};
 | 
						|
 | 
						|
}}
 | 
						|
 | 
						|
#endif /* slic3r_OptionsGroup_hpp_ */
 |