1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        ButtonAddParamDlg.h
3 // Purpose:     Dialog to add new parameter to button
4 // Author:      Alex Thuering
5 // Created:     11.10.2018
6 // Copyright:   (c) Alex Thuering
7 // Licence:     GPL
8 /////////////////////////////////////////////////////////////////////////////
9 
10 #include "ButtonAddParamDlg.h"
11 #include <wx/button.h>
12 #include <wx/intl.h>
13 #include <wx/string.h>
14 #include <wx/log.h>
15 #include <wxSVG/SVGSVGElement.h>
16 #include <wxSVG/SVGGElement.h>
17 
18 
19 //*)
20 
21 //(*IdInit(ButtonAddParamDlg)
22 const long ButtonAddParamDlg::ID_LISTBOX1 = wxNewId();
23 const long ButtonAddParamDlg::ID_TEXTCTRL1 = wxNewId();
24 const long ButtonAddParamDlg::ID_TEXTCTRL2 = wxNewId();
25 const long ButtonAddParamDlg::ID_PANEL1 = wxNewId();
26 const long ButtonAddParamDlg::ID_SVG_CTRL = wxNewId();
27 const long ButtonAddParamDlg::ID_SPLITTERWINDOW1 = wxNewId();
28 //*)
29 
BEGIN_EVENT_TABLE(ButtonAddParamDlg,wxDialog)30 BEGIN_EVENT_TABLE(ButtonAddParamDlg,wxDialog)
31 	//(*EventTable(ButtonAddParamDlg)
32 	//*)
33 END_EVENT_TABLE()
34 
35 ButtonAddParamDlg::ButtonAddParamDlg(wxWindow* parent, wxSVGSVGElement* rootElem,
36 		wxNodeList nodeList, vector<wxString> elements) {
37 	//(*Initialize(ButtonAddParamDlg)
38 	wxBoxSizer* BoxSizer1;
39 	wxBoxSizer* mainSizer;
40 	wxFlexGridSizer* FlexGridSizer1;
41 	wxPanel* panel1;
42 	wxStaticText* StaticText1;
43 	wxStaticText* StaticText2;
44 	wxStaticText* StaticText3;
45 	wxStdDialogButtonSizer* StdDialogButtonSizer1;
46 
47 	Create(parent, wxID_ANY, _("Add parameter"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER, _T("wxID_ANY"));
48 	SetClientSize(wxSize(750,400));
49 	mainSizer = new wxBoxSizer(wxVERTICAL);
50 	m_splitterWindow = new wxSplitterWindow(this, ID_SPLITTERWINDOW1, wxDefaultPosition, wxDefaultSize, wxSP_3D, _T("ID_SPLITTERWINDOW1"));
51 	m_splitterWindow->SetMinimumPaneSize(10);
52 	m_splitterWindow->SetSashGravity(0.5);
53 	panel1 = new wxPanel(m_splitterWindow, ID_PANEL1, wxPoint(6,5), wxDefaultSize, wxTAB_TRAVERSAL, _T("ID_PANEL1"));
54 	BoxSizer1 = new wxBoxSizer(wxVERTICAL);
55 	StaticText1 = new wxStaticText(panel1, wxID_ANY, _("Please select an SVG element\nfor new parameter:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
56 	BoxSizer1->Add(StaticText1, 0, wxBOTTOM|wxEXPAND, 5);
57 	m_elementsListBox = new wxListBox(panel1, ID_LISTBOX1, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_LISTBOX1"));
58 	BoxSizer1->Add(m_elementsListBox, 1, wxEXPAND, 5);
59 	FlexGridSizer1 = new wxFlexGridSizer(0, 2, 2, 2);
60 	StaticText2 = new wxStaticText(panel1, wxID_ANY, _("Fill:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
61 	FlexGridSizer1->Add(StaticText2, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
62 	m_fillCtrl = new wxTextCtrl(panel1, ID_TEXTCTRL1, _("Text"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
63 	m_fillCtrl->Disable();
64 	FlexGridSizer1->Add(m_fillCtrl, 1, wxLEFT|wxEXPAND, 5);
65 	StaticText3 = new wxStaticText(panel1, wxID_ANY, _("Stroke:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
66 	FlexGridSizer1->Add(StaticText3, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
67 	m_strokeCtrl = new wxTextCtrl(panel1, ID_TEXTCTRL2, _("Text"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL2"));
68 	m_strokeCtrl->Disable();
69 	FlexGridSizer1->Add(m_strokeCtrl, 1, wxLEFT|wxEXPAND, 5);
70 	BoxSizer1->Add(FlexGridSizer1, 0, wxEXPAND, 5);
71 	panel1->SetSizer(BoxSizer1);
72 	BoxSizer1->Fit(panel1);
73 	BoxSizer1->SetSizeHints(panel1);
74 	m_svgCtrl = new wxSVGCtrl(m_splitterWindow,ID_SVG_CTRL,wxDefaultPosition,wxDefaultSize,0,_T("ID_SVG_CTRL"));
75 	m_splitterWindow->SplitVertically(panel1, m_svgCtrl);
76 	mainSizer->Add(m_splitterWindow, 1, wxALL|wxEXPAND, 5);
77 	StdDialogButtonSizer1 = new wxStdDialogButtonSizer();
78 	StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_OK, wxEmptyString));
79 	StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_CANCEL, wxEmptyString));
80 	StdDialogButtonSizer1->Realize();
81 	mainSizer->Add(StdDialogButtonSizer1, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
82 	SetSizer(mainSizer);
83 	SetSizer(mainSizer);
84 	Layout();
85 
86 	Connect(ID_LISTBOX1,wxEVT_COMMAND_LISTBOX_SELECTED,(wxObjectEventFunction)&ButtonAddParamDlg::OnSelectSvgElement);
87 	//*)
88 
89 	m_nodeList = nodeList;
90 	CreateSvgDoc(rootElem->GetWidth().GetBaseVal(), rootElem->GetHeight().GetBaseVal(), rootElem->GetViewBox());
91 
92 	wxArrayString s;
93 	s.assign(elements.begin(), elements.end());
94 	m_elementsListBox->Set(s);
95 	m_elementsListBox->SetSelection(elements.size() - 1);
96 	wxCommandEvent evt;
97 	OnSelectSvgElement(evt);
98 
99 	m_splitterWindow->SetSashPosition(100);
100 }
101 
~ButtonAddParamDlg()102 ButtonAddParamDlg::~ButtonAddParamDlg() {
103 	//(*Destroy(ButtonAddParamDlg)
104 	//*)
105 	delete m_doc;
106 }
107 
GetSelection() const108 int ButtonAddParamDlg::GetSelection() const {
109 	return m_elementsListBox->GetSelection();
110 }
111 
CreateSvgDoc(double width,double height,const wxSVGRect & viewBox)112 wxSVGSVGElement* ButtonAddParamDlg::CreateSvgDoc(double width, double height, const wxSVGRect& viewBox) {
113 	m_doc = new wxSVGDocument;
114 	m_doc->SetRootElement(new wxSVGSVGElement());
115 	m_doc->GetRootElement()->SetWidth(width);
116 	m_doc->GetRootElement()->SetHeight(height);
117 	m_doc->GetRootElement()->SetViewBox(viewBox);
118 	m_svgCtrl->SetSVG(m_doc);
119 	return m_doc->GetRootElement();
120 }
121 
OnSelectSvgElement(wxCommandEvent & event)122 void ButtonAddParamDlg::OnSelectSvgElement(wxCommandEvent& event) {
123 	wxSVGElement* selectedElem = (wxSVGElement*) m_nodeList[GetSelection() + 1];
124 	// clear
125 	double width = m_doc->GetRootElement()->GetWidth().GetBaseVal();
126 	double height = m_doc->GetRootElement()->GetHeight().GetBaseVal();
127 	wxSVGRect viewBox = m_doc->GetRootElement()->GetViewBox();
128 	delete m_doc;
129 	wxSVGSVGElement* root = CreateSvgDoc(width, height, viewBox);
130 	// clione defs
131 	wxSVGElement* defs = (wxSVGElement*) m_nodeList[0]->GetFirstChild();
132 	if (defs != NULL && defs->GetDtd() == wxSVG_DEFS_ELEMENT) {
133 		root->AppendChild(defs->CloneNode());
134 	}
135 	// find out transforms, fill and stroke
136 	vector<wxSVGElement*> parentList;
137 	wxSVGElement* parent = (wxSVGElement*) selectedElem->GetParent();
138 	while (parent != NULL) {
139 		parentList.insert(parentList.begin(), parent);
140 		parent = (wxSVGElement*) parent->GetParent();
141 	}
142 	wxSVGTransformList tList;
143 	wxSVGPaint fill;
144 	wxSVGPaint stroke;
145 	double strokeWidth = 0;
146 	for (wxSVGElement* parentElem : parentList) {
147 		wxSVGTransformable* transformable = wxSVGTransformable::GetSVGTransformable(*parentElem);
148 		if (transformable != NULL && transformable->GetTransform().GetBaseVal().size() > 0) {
149 			tList.Add(transformable->GetTransform().GetBaseVal()[0]);
150 		}
151 		wxSVGStylable* stylable = wxSVGStylable::GetSVGStylable(*parentElem);
152 		if (stylable != NULL) {
153 			if (stylable->GetFill().Ok()) {
154 				fill = stylable->GetFill();
155 			}
156 			if (stylable->GetStroke().Ok()) {
157 				stroke = stylable->GetStroke();
158 				strokeWidth = stylable->GetStrokeWidth();
159 			}
160 		}
161 	}
162 	// create g-element and clone selected
163 	wxSVGGElement* gElem = new wxSVGGElement();
164 	gElem->SetTransform(tList);
165 	gElem->SetFill(fill);
166 	gElem->SetStroke(stroke);
167 	gElem->SetStrokeWidth(strokeWidth);
168 	gElem->AddChild(selectedElem->CloneNode());
169 	root->AppendChild(gElem);
170 	m_svgCtrl->Refresh();
171 
172 	// display fill and stroke
173 	wxSVGStylable* stylable = wxSVGStylable::GetSVGStylable(*selectedElem);
174 	if (stylable != NULL) {
175 		if (stylable->GetFill().Ok()) {
176 			fill = stylable->GetFill();
177 		}
178 		if (stylable->GetStroke().Ok()) {
179 			stroke = stylable->GetStroke();
180 			strokeWidth = stylable->GetStrokeWidth();
181 		}
182 	}
183 	m_fillCtrl->SetValue(fill.GetCSSText());
184 	m_strokeCtrl->SetValue(stroke.GetCSSText());
185 }
186