#ifndef slic3r_GUI_ObjectList_hpp_ #define slic3r_GUI_ObjectList_hpp_ #include #include #include #include #include #include "Event.hpp" #include "wxExtensions.hpp" class wxBoxSizer; class wxMenuItem; class ObjectDataViewModel; class MenuWithSeparators; namespace Slic3r { class ConfigOptionsGroup; class DynamicPrintConfig; class ModelObject; class ModelVolume; enum class ModelVolumeType : int; // FIXME: broken build on mac os because of this is missing: typedef std::vector t_config_option_keys; typedef std::map> FreqSettingsBundle; // category -> vector ( option ; label ) typedef std::map< std::string, std::vector< std::pair > > settings_menu_hierarchy; typedef std::vector ModelVolumePtrs; namespace GUI { wxDECLARE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent); struct ItemForDelete { ItemType type; int obj_idx; int sub_obj_idx; ItemForDelete(ItemType type, int obj_idx, int sub_obj_idx) : type(type), obj_idx(obj_idx), sub_obj_idx(sub_obj_idx) {} bool operator==(const ItemForDelete& r) const { return (type == r.type && obj_idx == r.obj_idx && sub_obj_idx == r.sub_obj_idx); } bool operator<(const ItemForDelete& r) const { if (obj_idx != r.obj_idx) return (obj_idx < r.obj_idx); return (sub_obj_idx < r.sub_obj_idx); } }; class ObjectList : public wxDataViewCtrl { enum SELECTION_MODE { smUndef, smVolume, smInstance } m_selection_mode {smUndef}; struct dragged_item_data { void init(const int obj_idx, const int subobj_idx, const ItemType type) { m_obj_idx = obj_idx; m_type = type; if (m_type&itVolume) m_vol_idx = subobj_idx; else m_inst_idxs.insert(subobj_idx); } void init(const int obj_idx, const ItemType type) { m_obj_idx = obj_idx; m_type = type; } void clear() { m_obj_idx = -1; m_vol_idx = -1; m_inst_idxs.clear(); m_type = itUndef; } int obj_idx() const { return m_obj_idx; } int sub_obj_idx() const { return m_vol_idx; } ItemType type() const { return m_type; } std::set& inst_idxs() { return m_inst_idxs; } private: int m_obj_idx = -1; int m_vol_idx = -1; std::set m_inst_idxs{}; ItemType m_type = itUndef; } m_dragged_data; wxBoxSizer *m_sizer {nullptr}; wxWindow *m_parent {nullptr}; ScalableBitmap m_bmp_modifiermesh; ScalableBitmap m_bmp_solidmesh; ScalableBitmap m_bmp_support_enforcer; ScalableBitmap m_bmp_support_blocker; ScalableBitmap m_bmp_manifold_warning; ScalableBitmap m_bmp_cog; MenuWithSeparators m_menu_object; MenuWithSeparators m_menu_part; MenuWithSeparators m_menu_sla_object; MenuWithSeparators m_menu_instance; wxMenuItem* m_menu_item_split { nullptr }; wxMenuItem* m_menu_item_split_part { nullptr }; wxMenuItem* m_menu_item_settings { nullptr }; wxMenuItem* m_menu_item_split_instances { nullptr }; std::vector m_bmp_vector; int m_selected_object_id = -1; bool m_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler // calls this method again and again and again bool m_prevent_update_extruder_in_config = false; // We use this flag to avoid updating of the extruder value in config // during updating of the extruder count. bool m_prevent_canvas_selection_update = false; // This flag prevents changing selection on the canvas. See function // update_settings_items - updating canvas selection is undesirable, // because it would turn off the gizmos (mainly a problem for the SLA gizmo) int m_selected_row = 0; wxDataViewItem m_last_selected_item {nullptr}; #if 0 FreqSettingsBundle m_freq_settings_fff; FreqSettingsBundle m_freq_settings_sla; #endif public: ObjectList(wxWindow* parent); ~ObjectList(); std::map CATEGORY_ICON; ObjectDataViewModel *m_objects_model{ nullptr }; DynamicPrintConfig *m_config {nullptr}; std::vector *m_objects{ nullptr }; void create_objects_ctrl(); void create_popup_menus(); wxDataViewColumn* create_objects_list_extruder_column(int extruders_count); void update_objects_list_extruder_column(int extruders_count); // show/hide "Extruder" column for Objects List void set_extruder_column_hidden(const bool hide) const; // update extruder in current config void update_extruder_in_config(const wxDataViewItem& item); // update changed name in the object model void update_name_in_model(const wxDataViewItem& item) const; void update_extruder_values_for_items(const int max_extruder); void init_icons(); void msw_rescale_icons(); // Get obj_idx and vol_idx values for the selected (by default) or an adjusted item void get_selected_item_indexes(int& obj_idx, int& vol_idx, const wxDataViewItem& item = wxDataViewItem(0)); // Get count of errors in the mesh int get_mesh_errors_count(const int obj_idx, const int vol_idx = -1) const; /* Get list of errors in the mesh. Return value is a string, used for the tooltip * Function without parameters is for a call from Manipulation panel, * when we don't know parameters of selected item */ wxString get_mesh_errors_list(const int obj_idx, const int vol_idx = -1) const; wxString get_mesh_errors_list(); void set_tooltip_for_item(const wxPoint& pt); void selection_changed(); void show_context_menu(); void key_event(wxKeyEvent& event); void get_settings_choice(const wxString& category_name); void get_freq_settings_choice(const wxString& bundle_name); void update_settings_item(); wxMenu* append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type); void append_menu_items_add_volume(wxMenu* menu); wxMenuItem* append_menu_item_split(wxMenu* menu); wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu); wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu); void append_menu_items_osx(wxMenu* menu); wxMenuItem* append_menu_item_fix_through_netfabb(wxMenu* menu); void append_menu_item_export_stl(wxMenu* menu) const ; void append_menu_item_change_extruder(wxMenu* menu) const; void append_menu_item_delete(wxMenu* menu); void create_object_popupmenu(wxMenu *menu); void create_sla_object_popupmenu(wxMenu*menu); void create_part_popupmenu(wxMenu*menu); void create_instance_popupmenu(wxMenu*menu); wxMenu* create_settings_popupmenu(wxMenu *parent_menu); void create_freq_settings_popupmenu(wxMenu *parent_menu); void update_opt_keys(t_config_option_keys& t_optopt_keys); void load_subobject(ModelVolumeType type); void load_part(ModelObject* model_object, std::vector> &volumes_info, ModelVolumeType type); void load_generic_subobject(const std::string& type_name, const ModelVolumeType type); void del_object(const int obj_idx); void del_subobject_item(wxDataViewItem& item); void del_settings_from_config(); void del_instances_from_object(const int obj_idx); bool del_subobject_from_object(const int obj_idx, const int idx, const int type); void split(); bool get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume); bool is_splittable(); bool selected_instances_of_same_object(); bool can_split_instances(); wxPoint get_mouse_position_in_control(); wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; void changed_object(const int obj_idx = -1) const; void part_selection_changed(); // Add object to the list void add_object_to_list(size_t obj_idx); // Delete object from the list void delete_object_from_list(); void delete_object_from_list(const size_t obj_idx); void delete_volume_from_list(const size_t obj_idx, const size_t vol_idx); void delete_instance_from_list(const size_t obj_idx, const size_t inst_idx); void delete_from_model_and_list(const ItemType type, const int obj_idx, const int sub_obj_idx); void delete_from_model_and_list(const std::vector& items_for_delete); // Delete all objects from the list void delete_all_objects_from_list(); // Increase instances count void increase_object_instances(const size_t obj_idx, const size_t num); // Decrease instances count void decrease_object_instances(const size_t obj_idx, const size_t num); // #ys_FIXME_to_delete // Unselect all objects in the list on c++ side void unselect_objects(); // Select current object in the list on c++ side void select_current_object(int idx); // Select current volume in the list on c++ side void select_current_volume(int idx, int vol_idx); // Remove objects/sub-object from the list void remove(); void init_objects(); bool multiple_selection() const ; bool is_selected(const ItemType type) const; void update_selections(); void update_selections_on_canvas(); void select_item(const wxDataViewItem& item); void select_items(const wxDataViewItemArray& sels); void select_all(); void select_item_all_children(); void update_selection_mode(); bool check_last_selection(wxString& msg_str); // correct current selections to avoid of the possible conflicts void fix_multiselection_conflicts(); ModelVolume* get_selected_model_volume(); void change_part_type(); void last_volume_is_deleted(const int obj_idx); bool has_multi_part_objects(); void update_settings_items(); void update_object_menu(); void instances_to_separated_object(const int obj_idx, const std::set& inst_idx); void instances_to_separated_objects(const int obj_idx); void split_instances(); void rename_item(); void fix_through_netfabb(); void update_item_error_icon(const int obj_idx, int vol_idx) const ; void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes); void paste_objects_into_list(const std::vector& object_idxs); void msw_rescale(); private: void OnChar(wxKeyEvent& event); void OnContextMenu(wxDataViewEvent &event); void OnBeginDrag(wxDataViewEvent &event); void OnDropPossible(wxDataViewEvent &event); void OnDrop(wxDataViewEvent &event); bool can_drop(const wxDataViewItem& item) const ; void ItemValueChanged(wxDataViewEvent &event); void OnEditingDone(wxDataViewEvent &event); void show_multi_selection_menu(); void extruder_selection(); void set_extruder_for_selected_items(const int extruder) const ; std::vector get_options(const bool is_part); const std::vector& get_options_for_bundle(const wxString& bundle_name); void get_options_menu(settings_menu_hierarchy& settings_menu, const bool is_part); }; }} #endif //slic3r_GUI_ObjectList_hpp_