mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-21 05:37:52 -06:00
First experiments with ObjectsTreeList
This commit is contained in:
parent
993294579d
commit
db549e8609
4 changed files with 992 additions and 2 deletions
|
@ -4,6 +4,9 @@
|
|||
#include <wx/checklst.h>
|
||||
#include <wx/combo.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/dc.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup
|
||||
{
|
||||
|
@ -50,4 +53,412 @@ public:
|
|||
void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; }
|
||||
};
|
||||
|
||||
// *****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyObjectTreeModelNode: a node inside MyObjectTreeModel
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class MyObjectTreeModelNode;
|
||||
WX_DEFINE_ARRAY_PTR(MyObjectTreeModelNode*, MyObjectTreeModelNodePtrArray);
|
||||
|
||||
class MyObjectTreeModelNode
|
||||
{
|
||||
MyObjectTreeModelNode* m_parent;
|
||||
MyObjectTreeModelNodePtrArray m_children;
|
||||
public:
|
||||
MyObjectTreeModelNode( const wxString &name) {
|
||||
m_parent = NULL;
|
||||
m_name = name;
|
||||
m_copy = "1";
|
||||
m_scale = "100%";
|
||||
}
|
||||
|
||||
MyObjectTreeModelNode( MyObjectTreeModelNode* parent,
|
||||
const wxString& sub_obj) {
|
||||
m_parent = parent;
|
||||
m_name = sub_obj;
|
||||
m_copy = wxEmptyString;
|
||||
m_scale = wxEmptyString;
|
||||
}
|
||||
|
||||
~MyObjectTreeModelNode()
|
||||
{
|
||||
// free all our children nodes
|
||||
size_t count = m_children.GetCount();
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
MyObjectTreeModelNode *child = m_children[i];
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
wxString m_name;
|
||||
wxString m_copy;
|
||||
wxString m_scale;
|
||||
bool m_container = false;
|
||||
|
||||
bool IsContainer() const
|
||||
{
|
||||
return m_container;
|
||||
}
|
||||
|
||||
MyObjectTreeModelNode* GetParent()
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
MyObjectTreeModelNodePtrArray& GetChildren()
|
||||
{
|
||||
return m_children;
|
||||
}
|
||||
MyObjectTreeModelNode* GetNthChild(unsigned int n)
|
||||
{
|
||||
return m_children.Item(n);
|
||||
}
|
||||
void Insert(MyObjectTreeModelNode* child, unsigned int n)
|
||||
{
|
||||
m_children.Insert(child, n);
|
||||
}
|
||||
void Append(MyObjectTreeModelNode* child)
|
||||
{
|
||||
if (!m_container)
|
||||
m_container = true;
|
||||
m_children.Add(child);
|
||||
}
|
||||
unsigned int GetChildCount() const
|
||||
{
|
||||
return m_children.GetCount();
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyObjectTreeModel
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class MyObjectTreeModel :public wxDataViewModel
|
||||
{
|
||||
std::set<MyObjectTreeModelNode*> m_objects;
|
||||
public:
|
||||
MyObjectTreeModel();
|
||||
~MyObjectTreeModel()
|
||||
{
|
||||
for (auto object : m_objects)
|
||||
delete object;
|
||||
}
|
||||
|
||||
// helper method for wxLog
|
||||
|
||||
wxString GetName(const wxDataViewItem &item) const;
|
||||
wxString GetCopyCnt(const wxDataViewItem &item) const;
|
||||
wxString GetScale(const wxDataViewItem &item) const;
|
||||
|
||||
// helper methods to change the model
|
||||
|
||||
// void AddToClassical(const wxString &title, const wxString &artist,
|
||||
// unsigned int year);
|
||||
// void Delete(const wxDataViewItem &item);
|
||||
|
||||
virtual unsigned int GetColumnCount() const override { return 3;}
|
||||
virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); }
|
||||
|
||||
virtual void GetValue(wxVariant &variant,
|
||||
const wxDataViewItem &item, unsigned int col) const override;
|
||||
virtual bool SetValue(const wxVariant &variant,
|
||||
const wxDataViewItem &item, unsigned int col) override;
|
||||
|
||||
// virtual bool IsEnabled(const wxDataViewItem &item,
|
||||
// unsigned int col) const override;
|
||||
|
||||
virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override;
|
||||
virtual bool IsContainer(const wxDataViewItem &item) const override;
|
||||
virtual unsigned int GetChildren(const wxDataViewItem &parent,
|
||||
wxDataViewItemArray &array) const override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyMusicTreeModelNode: a node inside MyMusicTreeModel
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class MyMusicTreeModelNode;
|
||||
WX_DEFINE_ARRAY_PTR(MyMusicTreeModelNode*, MyMusicTreeModelNodePtrArray);
|
||||
|
||||
class MyMusicTreeModelNode
|
||||
{
|
||||
public:
|
||||
MyMusicTreeModelNode(MyMusicTreeModelNode* parent,
|
||||
const wxString &title, const wxString &artist,
|
||||
unsigned int year)
|
||||
{
|
||||
m_parent = parent;
|
||||
|
||||
m_title = title;
|
||||
m_artist = artist;
|
||||
m_year = year;
|
||||
m_quality = "good";
|
||||
|
||||
m_container = false;
|
||||
}
|
||||
|
||||
MyMusicTreeModelNode(MyMusicTreeModelNode* parent,
|
||||
const wxString &branch)
|
||||
{
|
||||
m_parent = parent;
|
||||
|
||||
m_title = branch;
|
||||
m_year = -1;
|
||||
|
||||
m_container = true;
|
||||
}
|
||||
|
||||
~MyMusicTreeModelNode()
|
||||
{
|
||||
// free all our children nodes
|
||||
size_t count = m_children.GetCount();
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
MyMusicTreeModelNode *child = m_children[i];
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsContainer() const
|
||||
{
|
||||
return m_container;
|
||||
}
|
||||
|
||||
MyMusicTreeModelNode* GetParent()
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
MyMusicTreeModelNodePtrArray& GetChildren()
|
||||
{
|
||||
return m_children;
|
||||
}
|
||||
MyMusicTreeModelNode* GetNthChild(unsigned int n)
|
||||
{
|
||||
return m_children.Item(n);
|
||||
}
|
||||
void Insert(MyMusicTreeModelNode* child, unsigned int n)
|
||||
{
|
||||
m_children.Insert(child, n);
|
||||
}
|
||||
void Append(MyMusicTreeModelNode* child)
|
||||
{
|
||||
m_children.Add(child);
|
||||
}
|
||||
unsigned int GetChildCount() const
|
||||
{
|
||||
return m_children.GetCount();
|
||||
}
|
||||
|
||||
public: // public to avoid getters/setters
|
||||
wxString m_title;
|
||||
wxString m_artist;
|
||||
int m_year;
|
||||
wxString m_quality;
|
||||
|
||||
// TODO/FIXME:
|
||||
// the GTK version of wxDVC (in particular wxDataViewCtrlInternal::ItemAdded)
|
||||
// needs to know in advance if a node is or _will be_ a container.
|
||||
// Thus implementing:
|
||||
// bool IsContainer() const
|
||||
// { return m_children.GetCount()>0; }
|
||||
// doesn't work with wxGTK when MyMusicTreeModel::AddToClassical is called
|
||||
// AND the classical node was removed (a new node temporary without children
|
||||
// would be added to the control)
|
||||
bool m_container;
|
||||
|
||||
private:
|
||||
MyMusicTreeModelNode *m_parent;
|
||||
MyMusicTreeModelNodePtrArray m_children;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyMusicTreeModel
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Implement this data model
|
||||
Title Artist Year Judgement
|
||||
--------------------------------------------------------------------------
|
||||
1: My Music:
|
||||
2: Pop music
|
||||
3: You are not alone Michael Jackson 1995 good
|
||||
4: Take a bow Madonna 1994 good
|
||||
5: Classical music
|
||||
6: Ninth Symphony Ludwig v. Beethoven 1824 good
|
||||
7: German Requiem Johannes Brahms 1868 good
|
||||
*/
|
||||
|
||||
class MyMusicTreeModel : public wxDataViewModel
|
||||
{
|
||||
public:
|
||||
MyMusicTreeModel();
|
||||
~MyMusicTreeModel()
|
||||
{
|
||||
if (m_root)
|
||||
delete m_root;
|
||||
|
||||
}
|
||||
|
||||
// helper method for wxLog
|
||||
|
||||
wxString GetTitle(const wxDataViewItem &item) const;
|
||||
wxString GetArtist(const wxDataViewItem &item) const;
|
||||
int GetYear(const wxDataViewItem &item) const;
|
||||
|
||||
// helper methods to change the model
|
||||
|
||||
void AddToClassical(const wxString &title, const wxString &artist,
|
||||
unsigned int year);
|
||||
void Delete(const wxDataViewItem &item);
|
||||
|
||||
wxDataViewItem GetNinthItem() const
|
||||
{
|
||||
return wxDataViewItem(m_ninth);
|
||||
}
|
||||
|
||||
// override sorting to always sort branches ascendingly
|
||||
|
||||
int Compare(const wxDataViewItem &item1, const wxDataViewItem &item2,
|
||||
unsigned int column, bool ascending) const override/*wxOVERRIDE*/;
|
||||
|
||||
// implementation of base class virtuals to define model
|
||||
|
||||
virtual unsigned int GetColumnCount() const override/*wxOVERRIDE*/
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
virtual wxString GetColumnType(unsigned int col) const override/*wxOVERRIDE*/
|
||||
{
|
||||
if (col == 2)
|
||||
return wxT("long");
|
||||
|
||||
return wxT("string");
|
||||
}
|
||||
|
||||
virtual void GetValue(wxVariant &variant,
|
||||
const wxDataViewItem &item, unsigned int col) const override/*wxOVERRIDE*/;
|
||||
virtual bool SetValue(const wxVariant &variant,
|
||||
const wxDataViewItem &item, unsigned int col) override/*wxOVERRIDE*/;
|
||||
|
||||
virtual bool IsEnabled(const wxDataViewItem &item,
|
||||
unsigned int col) const override/*wxOVERRIDE*/;
|
||||
|
||||
virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override/*wxOVERRIDE*/;
|
||||
virtual bool IsContainer(const wxDataViewItem &item) const override/*wxOVERRIDE*/;
|
||||
virtual unsigned int GetChildren(const wxDataViewItem &parent,
|
||||
wxDataViewItemArray &array) const override/*wxOVERRIDE*/;
|
||||
|
||||
private:
|
||||
MyMusicTreeModelNode* m_root;
|
||||
|
||||
// pointers to some "special" nodes of the tree:
|
||||
MyMusicTreeModelNode* m_pop;
|
||||
MyMusicTreeModelNode* m_classical;
|
||||
MyMusicTreeModelNode* m_ninth;
|
||||
|
||||
// ??
|
||||
bool m_classicalMusicIsKnownToControl;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyCustomRenderer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class MyCustomRenderer : public wxDataViewCustomRenderer
|
||||
{
|
||||
public:
|
||||
// This renderer can be either activatable or editable, for demonstration
|
||||
// purposes. In real programs, you should select whether the user should be
|
||||
// able to activate or edit the cell and it doesn't make sense to switch
|
||||
// between the two -- but this is just an example, so it doesn't stop us.
|
||||
explicit MyCustomRenderer(wxDataViewCellMode mode)
|
||||
: wxDataViewCustomRenderer("string", mode, wxALIGN_CENTER)
|
||||
{ }
|
||||
|
||||
virtual bool Render(wxRect rect, wxDC *dc, int state) override/*wxOVERRIDE*/
|
||||
{
|
||||
dc->SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc->SetPen(*wxTRANSPARENT_PEN);
|
||||
|
||||
rect.Deflate(2);
|
||||
dc->DrawRoundedRectangle(rect, 5);
|
||||
|
||||
RenderText(m_value,
|
||||
0, // no offset
|
||||
wxRect(dc->GetTextExtent(m_value)).CentreIn(rect),
|
||||
dc,
|
||||
state);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool ActivateCell(const wxRect& WXUNUSED(cell),
|
||||
wxDataViewModel *WXUNUSED(model),
|
||||
const wxDataViewItem &WXUNUSED(item),
|
||||
unsigned int WXUNUSED(col),
|
||||
const wxMouseEvent *mouseEvent) override/*wxOVERRIDE*/
|
||||
{
|
||||
wxString position;
|
||||
if (mouseEvent)
|
||||
position = wxString::Format("via mouse at %d, %d", mouseEvent->m_x, mouseEvent->m_y);
|
||||
else
|
||||
position = "from keyboard";
|
||||
// wxLogMessage("MyCustomRenderer ActivateCell() %s", position);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual wxSize GetSize() const override/*wxOVERRIDE*/
|
||||
{
|
||||
return wxSize(60, 20);
|
||||
}
|
||||
|
||||
virtual bool SetValue(const wxVariant &value) override/*wxOVERRIDE*/
|
||||
{
|
||||
m_value = value.GetString();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool GetValue(wxVariant &WXUNUSED(value)) const override/*wxOVERRIDE*/{ return true; }
|
||||
|
||||
virtual bool HasEditorCtrl() const override/*wxOVERRIDE*/{ return true; }
|
||||
|
||||
virtual wxWindow*
|
||||
CreateEditorCtrl(wxWindow* parent,
|
||||
wxRect labelRect,
|
||||
const wxVariant& value) override/*wxOVERRIDE*/
|
||||
{
|
||||
wxTextCtrl* text = new wxTextCtrl(parent, wxID_ANY, value,
|
||||
labelRect.GetPosition(),
|
||||
labelRect.GetSize(),
|
||||
wxTE_PROCESS_ENTER);
|
||||
text->SetInsertionPointEnd();
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value) override/*wxOVERRIDE*/
|
||||
{
|
||||
wxTextCtrl* text = wxDynamicCast(ctrl, wxTextCtrl);
|
||||
if (!text)
|
||||
return false;
|
||||
|
||||
value = text->GetValue();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_value;
|
||||
};
|
||||
// *****************************************************************************
|
||||
|
||||
|
||||
|
||||
#endif // slic3r_GUI_wxExtensions_hpp_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue