]> git.saurik.com Git - wxWidgets.git/blob - contrib/utils/wxrcedit/propframe.cpp
implemented IsModified() and DiscardEdits()
[wxWidgets.git] / contrib / utils / wxrcedit / propframe.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Author: Vaclav Slavik
3 // Created: 2000/05/05
4 // RCS-ID: $Id$
5 // Copyright: (c) 2000 Vaclav Slavik
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 #ifdef __GNUG__
10 #pragma implementation "propframe.h"
11 #endif
12
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #include "wx/wx.h"
21 #include "wx/xrc/xml.h"
22 #include "wx/config.h"
23 #include "splittree.h"
24 #include "xmlhelpr.h"
25 #include "propframe.h"
26 #include "nodehnd.h"
27 #include "propedit.h"
28 #include "pe_basic.h"
29 #include "pe_adv.h"
30 #include "editor.h"
31
32 // ------------- support classes --------
33
34
35 class PropsTree: public wxRemotelyScrolledTreeCtrl
36 {
37 public:
38 PropsTree(wxWindow* parent, wxWindowID id, const wxPoint& pt = wxDefaultPosition,
39 const wxSize& sz = wxDefaultSize, long style = wxTR_HAS_BUTTONS)
40 : wxRemotelyScrolledTreeCtrl(parent, id, pt, sz, style),
41 m_EditCtrl(NULL)
42 {
43 #if 0
44 // VS: Don't do it, it is *extremely* ugly.
45 // FIXME: find a better solution.
46
47 //make text larger so controls will fit properly
48 wxFont font = GetFont();
49 font.SetPointSize(font.GetPointSize()*1.5);
50 SetFont(font);
51 #endif
52 }
53
54 void OnPaint(wxPaintEvent& event)
55 {
56 wxPaintDC dc(this);
57
58 wxTreeCtrl::OnPaint(event);
59
60 // Reset the device origin since it may have been set
61 dc.SetDeviceOrigin(0, 0);
62
63 wxPen pen(wxColour(_T("BLACK")), 1, wxSOLID);
64 dc.SetPen(pen);
65
66 dc.SetBrush(* wxTRANSPARENT_BRUSH);
67
68 wxSize clientSize = GetClientSize();
69 wxRect itemRect;
70 int cy=0;
71 wxTreeItemId h, lastH;
72 for(h=GetFirstVisibleItem();h;h=GetNextVisible(h))
73 {
74 if (h.IsOk() && GetBoundingRect(h, itemRect))
75 {
76 cy = itemRect.GetTop();
77
78 dc.DrawLine(0, cy, clientSize.x, cy);
79 lastH = h;
80 }
81 }
82 if (lastH.IsOk() && GetBoundingRect(lastH, itemRect))
83 {
84 cy = itemRect.GetBottom();
85 dc.DrawLine(0, cy, clientSize.x, cy);
86 }
87 }
88
89 void OnSelChange(wxTreeEvent& event)
90 {
91 if (m_EditCtrl != NULL)
92 {
93 m_EditCtrl->EndEdit();
94 m_EditCtrl = NULL;
95 }
96
97 wxTreeItemId item = event.GetItem();
98 PETreeData *dt = (PETreeData*)GetItemData(item);
99 if (dt != NULL)
100 {
101 wxRect bounding;
102 GetBoundingRect(item, bounding);
103
104 bounding.SetX(0);
105 bounding.SetWidth(GetCompanionWindow()->GetSize().x);
106 dt->EditCtrl->BeginEdit(bounding, item);
107 m_EditCtrl = dt->EditCtrl;
108 }
109 }
110
111 void ClearProps()
112 {
113 DeleteAllItems();
114 AddRoot(_("Properties"));
115 if (m_EditCtrl)
116 {
117 m_EditCtrl->EndEdit();
118 m_EditCtrl = NULL;
119 }
120 }
121
122 void OnScroll(wxScrollWinEvent& event)
123 {
124 event.Skip();
125 if (event.GetOrientation() == wxHORIZONTAL) return;
126 if (!m_EditCtrl) return;
127
128 wxTreeItemId id = GetSelection();
129 wxRect bounding;
130 GetBoundingRect(id, bounding);
131
132 m_EditCtrl->Move(-1, bounding.y);
133 }
134
135 PropEditCtrl *m_EditCtrl;
136
137 DECLARE_EVENT_TABLE()
138 };
139
140 BEGIN_EVENT_TABLE(PropsTree, wxRemotelyScrolledTreeCtrl)
141 EVT_PAINT(PropsTree::OnPaint)
142 EVT_TREE_SEL_CHANGED(-1, PropsTree::OnSelChange)
143 EVT_SCROLLWIN(PropsTree::OnScroll)
144 END_EVENT_TABLE()
145
146
147 class PropsValueWindow: public wxTreeCompanionWindow
148 {
149 public:
150 PropsValueWindow(wxWindow* parent, wxWindowID id = -1,
151 const wxPoint& pos = wxDefaultPosition,
152 const wxSize& sz = wxDefaultSize,
153 long style = 0)
154 : wxTreeCompanionWindow(parent, id, pos, sz, style) {}
155
156 virtual void DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect)
157 {
158 if (m_treeCtrl)
159 {
160 PETreeData *data = (PETreeData*)m_treeCtrl->GetItemData(id);
161 wxString text;
162 if (data != NULL) text = data->EditCtrl->GetValueAsText(id);
163 dc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID));
164 dc.DrawRectangle(rect);
165 dc.SetTextForeground(* wxBLACK);
166 dc.SetBackgroundMode(wxTRANSPARENT);
167
168 int textW, textH;
169 dc.GetTextExtent(text, & textW, & textH);
170
171 int x = 5;
172 int y = rect.GetY() + wxMax(0, (rect.GetHeight() - textH) / 2);
173
174 dc.DrawText(text, x, y);
175 }
176 }
177
178 void OnClick(wxMouseEvent& event)
179 {
180 int flags;
181 wxTreeItemId item = GetTreeCtrl()->HitTest(wxPoint(1, event.GetY()), flags);
182 if (item.IsOk())
183 {
184 GetTreeCtrl()->SelectItem(item);
185 }
186 }
187
188 DECLARE_EVENT_TABLE()
189 };
190
191 BEGIN_EVENT_TABLE(PropsValueWindow, wxTreeCompanionWindow)
192 EVT_LEFT_DOWN(PropsValueWindow::OnClick)
193 END_EVENT_TABLE()
194
195
196
197 // ------------- properties frame --------
198
199
200
201 PropertiesFrame* PropertiesFrame::ms_Instance = NULL;
202
203 PropertiesFrame *PropertiesFrame::Get()
204 {
205 if (ms_Instance == NULL)
206 {
207 (void)new PropertiesFrame;
208 ms_Instance->Show(TRUE);
209 }
210 return ms_Instance;
211 }
212
213 PropertiesFrame::PropertiesFrame()
214 : wxFrame(EditorFrame::Get(), -1, _("Properties"),
215 wxDefaultPosition, wxDefaultSize,
216 wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR
217 #ifdef __WXMSW__
218 | wxFRAME_TOOL_WINDOW
219 #endif
220 )
221 {
222 ms_Instance = this;
223 m_Node = NULL;
224
225 m_scrolledWindow = new wxSplitterScrolledWindow(this, -1, wxDefaultPosition,
226 wxDefaultSize, wxNO_BORDER | wxCLIP_CHILDREN | wxVSCROLL);
227 m_splitter = new wxThinSplitterWindow(m_scrolledWindow, -1, wxDefaultPosition,
228 wxDefaultSize, wxSP_3DBORDER | wxCLIP_CHILDREN /* | wxSP_LIVE_UPDATE */);
229 m_splitter->SetSashSize(2);
230 m_tree = new PropsTree(m_splitter, -1, wxDefaultPosition,
231 wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_NO_LINES | wxNO_BORDER );
232 m_tree->SetIndent(2);
233
234 m_valueWindow = new PropsValueWindow(m_splitter, -1, wxDefaultPosition,
235 wxDefaultSize, wxNO_BORDER);
236 m_valueWindow->SetBackgroundColour(m_tree->GetBackgroundColour());
237 m_splitter->SplitVertically(m_tree, m_valueWindow, wxConfig::Get()->Read(_T("propertiesframe_sash"), 100));
238 //m_splitter->AdjustScrollbars();
239 m_scrolledWindow->SetTargetWindow(m_tree);
240
241 m_scrolledWindow->EnableScrolling(FALSE, FALSE);
242
243 // Let the two controls know about each other
244 m_valueWindow->SetTreeCtrl(m_tree);
245 m_tree->SetCompanionWindow(m_valueWindow);
246
247 wxConfigBase *cfg = wxConfigBase::Get();
248 SetSize(wxRect(wxPoint(cfg->Read(_T("propertiesframe_x"), -1), cfg->Read(_T("propertiesframe_y"), -1)),
249 wxSize(cfg->Read(_T("propertiesframe_w"), 200), cfg->Read(_T("propertiesframe_h"), 200))));
250
251
252 m_EditCtrls.DeleteContents(TRUE);
253 m_EditCtrls.Put(_T("bool"), new PropEditCtrlBool(this));
254 m_EditCtrls.Put(_T("coord"), new PropEditCtrlCoord(this));
255 m_EditCtrls.Put(_T("color"), new PropEditCtrlColor(this));
256 m_EditCtrls.Put(_T("dimension"), new PropEditCtrlDim(this));
257 m_EditCtrls.Put(_T("flags"), new PropEditCtrlFlags(this));
258 m_EditCtrls.Put(_T("integer"), new PropEditCtrlInt(this));
259 m_EditCtrls.Put(_T("not_implemented"), new PropEditCtrlNull(this));
260 m_EditCtrls.Put(_T("text"), new PropEditCtrlTxt(this));
261 m_EditCtrls.Put(_T("xmlid"), new PropEditCtrlXRCID(this));
262 m_EditCtrls.Put(_T("font"), new PropEditCtrlFont(this));
263 m_EditCtrls.Put(_T("choice"), new PropEditCtrlChoice(this));
264 m_EditCtrls.Put(_T("file"), new PropEditCtrlFile(this));
265 m_EditCtrls.Put(_T("imagefile"), new PropEditCtrlImageFile(this));
266 m_EditCtrls.Put(_T(""), new PropEditCtrlNull(this));
267
268 ClearProps();
269 }
270
271
272
273 PropertiesFrame::~PropertiesFrame()
274 {
275 wxConfigBase *cfg = wxConfigBase::Get();
276 cfg->Write(_T("propertiesframe_x"), (long)GetPosition().x);
277 cfg->Write(_T("propertiesframe_y"), (long)GetPosition().y);
278 cfg->Write(_T("propertiesframe_w"), (long)GetSize().x);
279 cfg->Write(_T("propertiesframe_h"), (long)GetSize().y);
280 cfg->Write(_T("propertiesframe_sash"), (long)m_splitter->GetSashPosition());
281
282 ms_Instance = NULL;
283 }
284
285
286
287 void PropertiesFrame::ShowProps(wxXmlNode *node)
288 {
289 m_Node = node;
290
291 ClearProps();
292 AddSingleProp(PropertyInfo(_T("xmlid"), _T("XRCID"), wxEmptyString));
293 AddProps(NodeHandler::Find(node)->GetPropsList(node));
294
295 m_tree->Expand(m_tree->GetRootItem());
296 m_valueWindow->Refresh();
297 }
298
299
300
301 void PropertiesFrame::ClearProps()
302 {
303 ((PropsTree*)m_tree)->ClearProps();
304 }
305
306
307
308 void PropertiesFrame::AddProps(PropertyInfoArray& plist)
309 {
310 for (size_t i = 0; i < plist.GetCount(); i++)
311 {
312 AddSingleProp(plist[i]);
313 }
314 }
315
316
317
318 void PropertiesFrame::AddSingleProp(const PropertyInfo& pinfo, wxTreeItemId *root)
319 {
320 PropEditCtrl *pec = (PropEditCtrl*)m_EditCtrls.Get(pinfo.Type);
321 wxTreeItemId tid;
322 if (root != NULL) tid = *root;
323 else tid = m_tree->GetRootItem();
324
325 if (pec == NULL)
326 wxLogError(_("Unknown property type '%s'!"), pinfo.Type.c_str());
327 else
328 pec->CreateTreeEntry(tid, pinfo);
329 }
330