1 /*
2 * This file is part of wxSmith plugin for Code::Blocks Studio
3 * Copyright (C) 2006-2007 Bartlomiej Swiecki
4 *
5 * wxSmith is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * wxSmith is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with wxSmith. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * $Revision: 10771 $
19 * $Id: wxsitemeditor.cpp 10771 2016-02-06 14:29:31Z mortenmacfly $
20 * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/plugins/contrib/wxSmith/wxwidgets/wxsitemeditor.cpp $
21 */
22
23 #include <wx/dcmemory.h>
24 #include "wxsitemeditor.h"
25 #include "wxsitemeditorcontent.h"
26 #include "wxsitemfactory.h"
27 #include "wxsitemresdata.h"
28 #include "wxstoolspace.h"
29 #include "wxsitem.h"
30 #include "wxstool.h"
31 #include "wxsparent.h"
32 #include "../wxsproject.h"
33 #include <logmanager.h>
34
35 namespace
36 {
37 const long wxsInsPointId = wxNewId();
38 const long wxsInsIntoId = wxNewId();
39 const long wxsInsBeforeId = wxNewId();
40 const long wxsInsAfterId = wxNewId();
41 const long wxsDelId = wxNewId();
42 const long wxsPreviewId = wxNewId();
43 const long wxsQuickPropsId = wxNewId();
44
ToolIconSize()45 inline int ToolIconSize() { return Manager::Get()->GetConfigManager(_T("wxsmith"))->ReadInt(_T("/tooliconsize"),32L); }
PalIconSize()46 inline int PalIconSize() { return Manager::Get()->GetConfigManager(_T("wxsmith"))->ReadInt(_T("/paletteiconsize"),16L); }
47 }
48
wxsItemEditor(wxWindow * parent,wxsItemRes * Resource)49 wxsItemEditor::wxsItemEditor(wxWindow* parent,wxsItemRes* Resource):
50 wxsEditor(parent,wxEmptyString,Resource),
51 m_Data(0),
52 m_Content(0),
53 m_WidgetsSet(0),
54 m_VertSizer(0),
55 m_HorizSizer(0),
56 m_QPSizer(0),
57 m_OpsSizer(0),
58 m_QPArea(0),
59 m_InsIntoBtn(0),
60 m_InsBeforeBtn(0),
61 m_InsAfterBtn(0),
62 m_DelBtn(0),
63 m_PreviewBtn(0),
64 m_QuickPanelBtn(0),
65 m_TopPreview(0),
66 m_PreviewBackground(0),
67 m_InsType(itPoint),
68 m_InsTypeMask(itPoint),
69 m_QuickPropsOpen(false),
70 m_PopupCaller(0)
71 {
72 InitializeResourceData();
73 InitializeVisualStuff();
74 m_AllEditors.insert(this);
75 }
76
~wxsItemEditor()77 wxsItemEditor::~wxsItemEditor()
78 {
79 delete m_Data;
80 m_AllEditors.erase(this);
81 }
82
InitializeResourceData()83 void wxsItemEditor::InitializeResourceData()
84 {
85 m_Data = GetItemRes()->BuildResData(this);
86
87 if ( !m_Data->IsOk() )
88 {
89 // TODO: Some communicate (couldn't load resource) ?
90 }
91
92 if ( GetItemRes()->GetEditMode() == wxsItemRes::File )
93 {
94 InitFilename(GetXrcFileName());
95 SetTitle(m_Shortname);
96 }
97 else
98 {
99 InitFilename(GetWxsFileName());
100 SetTitle(m_Shortname);
101 }
102
103 }
104
InitializeVisualStuff()105 void wxsItemEditor::InitializeVisualStuff()
106 {
107 // Loading images if needed
108 InitializeImages();
109
110 // Creating content of editor window
111 m_VertSizer = new wxBoxSizer(wxVERTICAL);
112 m_WidgetsSet = new wxNotebook(this,-1);
113 BuildPalette(m_WidgetsSet);
114 m_ToolSpace = new wxsToolSpace(this,m_Data);
115 m_VertSizer->Add(m_ToolSpace,0,wxEXPAND);
116 m_HorizSizer = new wxBoxSizer(wxHORIZONTAL);
117 m_VertSizer->Add(m_HorizSizer,1,wxEXPAND);
118 m_VertSizer->Add(m_WidgetsSet,0,wxEXPAND);
119
120 m_Content = new wxsItemEditorContent(this,m_Data,this);
121 m_HorizSizer->Add(m_Content,1,wxEXPAND);
122
123 m_QPArea = new wxScrolledWindow(this,-1,wxDefaultPosition,wxDefaultSize,wxVSCROLL|wxHSCROLL|wxSUNKEN_BORDER/*|wxALWAYS_SHOW_SB*/);
124 m_QPArea->SetScrollbars(0,5,0,0);
125 m_HorizSizer->Add(m_QPArea,0,wxEXPAND);
126 m_QPSizer = new wxBoxSizer(wxVERTICAL);
127 m_QPArea->SetSizer(m_QPSizer);
128
129 m_OpsSizer = new wxBoxSizer(wxVERTICAL);
130 m_HorizSizer->Add(m_OpsSizer,0,wxEXPAND);
131
132 m_OpsSizer->Add(m_InsPointBtn = new wxBitmapButton(this,wxsInsPointId,m_InsPointImg));
133 m_OpsSizer->Add(m_InsIntoBtn = new wxBitmapButton(this,wxsInsIntoId,m_InsIntoImg));
134 m_OpsSizer->Add(m_InsBeforeBtn = new wxBitmapButton(this,wxsInsBeforeId,m_InsBeforeImg));
135 m_OpsSizer->Add(m_InsAfterBtn = new wxBitmapButton(this,wxsInsAfterId,m_InsAfterImg));
136 m_OpsSizer->Add(1,5);
137 m_OpsSizer->Add(m_DelBtn = new wxBitmapButton(this,wxsDelId,m_DelImg));
138 m_OpsSizer->Add(m_PreviewBtn = new wxBitmapButton(this,wxsPreviewId,m_PreviewImg));
139 m_OpsSizer->Add(1,5);
140 m_OpsSizer->Add(m_QuickPanelBtn = new wxBitmapButton(this,wxsQuickPropsId,m_QuickPropsImgOpen));
141 m_InsPointBtn ->SetToolTip(_("Insert new widgets by pointing with mouse"));
142 m_InsIntoBtn ->SetToolTip(_("Insert new widgets into current selection"));
143 m_InsBeforeBtn ->SetToolTip(_("Insert new widgets before current selection"));
144 m_InsAfterBtn ->SetToolTip(_("Insert new widgets after current selection"));
145 m_DelBtn ->SetToolTip(_("Delete current selection"));
146 m_PreviewBtn ->SetToolTip(_("Show preview"));
147 m_QuickPanelBtn->SetToolTip(_("Open / Close Quick Properties panel"));
148 SetSizer(m_VertSizer);
149
150 SetInsertionTypeMask(0);
151 ToggleQuickPropsPanel(false); // TODO: Shouldn't store initial state of panel somewhere?
152
153 RebuildPreview();
154 UpdateSelection();
155 }
156
ConfigChanged()157 void wxsItemEditor::ConfigChanged()
158 {
159 ReloadImages();
160 RefreshContents();
161 }
162
ReloadImages()163 void wxsItemEditor::ReloadImages()
164 {
165 m_ImagesLoaded = false;
166 InitializeImages();
167 for ( WindowSet::iterator i=m_AllEditors.begin(); i!=m_AllEditors.end(); ++i )
168 {
169 (*i)->RebuildIcons();
170 }
171 }
172
RefreshContents()173 void wxsItemEditor::RefreshContents()
174 {
175 for ( WindowSet::iterator i=m_AllEditors.begin(); i!=m_AllEditors.end(); ++i )
176 {
177 (*i)->RebuildPreview();
178 }
179 }
180
RebuildPreview()181 void wxsItemEditor::RebuildPreview()
182 {
183 // Checking if we've already initialized visual stuff
184 if ( !m_Content ) return;
185
186 m_Content->BeforePreviewChanged();
187 m_ToolSpace->BeforePreviewChanged();
188
189 Freeze();
190
191 // If there's previous preview, deleting it
192 if ( m_PreviewBackground )
193 {
194 m_Content->SetSizer(0);
195 m_PreviewBackground->Destroy();
196 m_PreviewBackground = 0;
197 m_TopPreview = 0;
198 }
199
200 // Generating preview
201 m_PreviewBackground = new wxPanel(m_Content,-1,wxDefaultPosition,wxDefaultSize,wxRAISED_BORDER);
202 wxObject* TopPreviewObject = m_Data->GetRootItem()->BuildPreview(m_PreviewBackground,0);
203 m_TopPreview = wxDynamicCast(TopPreviewObject,wxWindow);
204 if ( !m_TopPreview )
205 {
206 Manager::Get()->GetLogManager()->DebugLog(_T("One of root items returned class not derived from wxWindow"));
207 m_PreviewBackground->Destroy();
208 m_PreviewBackground = 0;
209 m_TopPreview = 0;
210 }
211 else
212 {
213 wxSizer* BackgroundSizer = new wxBoxSizer(wxHORIZONTAL);
214 BackgroundSizer->Add(m_TopPreview,0,0,0);
215 m_PreviewBackground->SetSizer(BackgroundSizer);
216 BackgroundSizer->Fit(m_PreviewBackground);
217 wxSizer* NewSizer = new wxGridSizer(1);
218 NewSizer->Add(m_PreviewBackground,0,wxALL,10);
219 #if !wxCHECK_VERSION(3, 0, 0)
220 m_Content->SetVirtualSizeHints(1,1);
221 #endif
222 m_Content->SetSizer(NewSizer);
223 #if wxCHECK_VERSION(3, 0, 0)
224 NewSizer->FitInside(m_Content);
225 #else
226 NewSizer->SetVirtualSizeHints(m_Content);
227 #endif
228 m_PreviewBackground->Layout();
229 m_Content->Layout();
230 m_HorizSizer->Layout();
231 }
232
233 m_ToolSpace->AfterPreviewChanged();
234 if ( m_ToolSpace->AreAnyTools() )
235 {
236 m_VertSizer->Show(m_ToolSpace,true,false);
237 }
238 else
239 {
240 m_VertSizer->Show(m_ToolSpace,false,false);
241 }
242 m_VertSizer->Layout();
243
244 Layout();
245 Thaw();
246 Refresh();
247
248 // Updating all informations in Content
249 m_Content->AfterPreviewChanged();
250 }
251
UpdateSelection()252 void wxsItemEditor::UpdateSelection()
253 {
254 // Checking if we've already initialized visual stuff
255 if ( !m_Content ) return;
256
257 // Updating drag point data
258 m_Content->RefreshSelection();
259 m_ToolSpace->RefreshSelection();
260
261 // Updating insertion type mask
262 wxsItem* Item = m_Data->GetRootSelection();
263 int itMask = 0;
264 if ( Item )
265 {
266 if ( Item->GetParent() )
267 {
268 // When sizer is added into non-sizer parent, no other items can be added to
269 // this parent
270 if ( Item->GetType() != wxsTSizer ||
271 Item->GetParent()->GetType() == wxsTSizer )
272 {
273 itMask |= itBefore | itAfter;
274 }
275 }
276
277 if ( Item->ConvertToParent() )
278 {
279 itMask |= itInto;
280 }
281 }
282 if ( m_Data->GetRootItem()->ConvertToParent() )
283 {
284 itMask |= itPoint;
285 }
286
287 SetInsertionTypeMask(itMask);
288 RebuildQuickProps(Item);
289
290 // TODO: Refresh set of available items inside palette
291 }
292
Save()293 bool wxsItemEditor::Save()
294 {
295 if ( !m_Data->Save() )
296 {
297 // TODO: Some message here please
298 }
299 UpdateModified();
300 return true;
301 }
302
GetModified() const303 bool wxsItemEditor::GetModified() const
304 {
305 return m_Data ? m_Data->GetModified() : false;
306 }
307
UpdateModified()308 void wxsItemEditor::UpdateModified()
309 {
310 if ( m_Data && m_Data->GetModified() )
311 {
312 SetTitle(_T("*") + GetShortName());
313 }
314 else
315 {
316 SetTitle(GetShortName());
317 }
318 }
319
CanUndo() const320 bool wxsItemEditor::CanUndo() const
321 {
322 return m_Data ? m_Data->CanUndo() : false;
323 }
324
CanRedo() const325 bool wxsItemEditor::CanRedo() const
326 {
327 return m_Data ? m_Data->CanRedo() : false;
328 }
329
Undo()330 void wxsItemEditor::Undo()
331 {
332 if ( m_Data ) m_Data->Undo();
333 }
334
Redo()335 void wxsItemEditor::Redo()
336 {
337 if ( m_Data ) m_Data->Redo();
338 }
339
HasSelection() const340 bool wxsItemEditor::HasSelection() const
341 {
342 return m_Data ? m_Data->AnySelected() : false;
343 }
344
CanPaste() const345 bool wxsItemEditor::CanPaste() const
346 {
347 return m_Data ? m_Data->CanPaste() : false;
348 }
349
IsReadOnly() const350 bool wxsItemEditor::IsReadOnly() const
351 {
352 return m_Data ? m_Data->IsReadOnly() : false;
353 }
354
Cut()355 void wxsItemEditor::Cut()
356 {
357 if ( m_Data ) m_Data->Cut();
358 }
359
Copy()360 void wxsItemEditor::Copy()
361 {
362 if ( m_Data ) m_Data->Copy();
363 }
364
Paste()365 void wxsItemEditor::Paste()
366 {
367 if ( !m_Data ) return;
368
369 wxsItem* Reference = GetReferenceItem(m_InsType);
370 if ( !Reference ) return;
371 wxsParent* Parent = Reference->GetParent();
372 int RefIndex = Parent ? Parent->GetChildIndex(Reference) : -1;
373
374 switch ( m_InsType )
375 {
376 case itAfter:
377 RefIndex++;
378 break;
379
380 case itInto:
381 Parent = Reference->ConvertToParent();
382 RefIndex = Parent ? Parent->GetChildCount() : 0;
383 break;
384
385 default:
386 break;
387 }
388
389 m_Data->Paste(Parent,RefIndex);
390 }
391
InsertRequest(const wxString & Name)392 void wxsItemEditor::InsertRequest(const wxString& Name)
393 {
394 const wxsItemInfo* Info = wxsItemFactory::GetInfo(Name);
395 if ( !Info ) return;
396 bool IsTool = Info->Type == wxsTTool;
397
398 if ( !IsTool && m_InsType==itPoint )
399 {
400 StartInsertPointSequence(Info);
401 return;
402 }
403
404 wxsItem* Reference = GetReferenceItem(m_InsType);
405 if ( !Reference )
406 {
407 Manager::Get()->GetLogManager()->DebugLog(_T("wxSmith: No item selected - couldn't create new item"));
408 return;
409 }
410
411 wxsItem* New = wxsItemFactory::Build(Name,m_Data);
412 if ( !New )
413 {
414 Manager::Get()->GetLogManager()->DebugLog(_T("wxSmith: Couldn't generate item inside factory"));
415 return;
416 }
417
418 m_Data->BeginChange();
419 wxsParent* Parent = Reference->GetParent();
420 int RefIndex = Parent ? Parent->GetChildIndex(Reference) : -1;
421
422 switch ( m_InsType )
423 {
424 case itAfter:
425 RefIndex++;
426 // We don't break here - continuing on itBefore code
427
428 case itBefore:
429 if ( Parent )
430 {
431 // Checking if this is tool, tools can be added
432 // into other tools or into resource only
433 if ( IsTool &&
434 ( !Parent->ConvertToTool() ||
435 !New->CanAddToParent(Parent,false)) )
436 {
437 // Trying to add to resource
438 if ( !New->ConvertToTool()->CanAddToResource(m_Data,true) )
439 {
440 delete New;
441 }
442 else
443 {
444 if ( m_Data->InsertNewTool(New->ConvertToTool()) )
445 {
446 m_Data->SelectItem(New,true);
447 }
448 }
449 }
450 else
451 {
452 if ( m_Data->InsertNew(New,Parent,RefIndex) )
453 {
454 m_Data->SelectItem(New,true);
455 }
456 }
457
458 }
459 else
460 {
461 delete New;
462 }
463 break;
464
465 case itInto:
466 case itPoint: // This will cover tools when itPoint is used
467 {
468 if ( IsTool &&
469 (!Reference->ConvertToTool() ||
470 !New->CanAddToParent(Reference->ConvertToParent(),false)) )
471 {
472 // Trying to add to resource
473 if ( !New->ConvertToTool()->CanAddToResource(m_Data,true) )
474 {
475 delete New;
476 }
477 else
478 {
479 if ( m_Data->InsertNewTool(New->ConvertToTool()) )
480 {
481 m_Data->SelectItem(New,true);
482 }
483 }
484 }
485 else
486 {
487 if ( m_Data->InsertNew(New,Reference->ConvertToParent(),-1) )
488 {
489 m_Data->SelectItem(New,true);
490 }
491 }
492 break;
493 }
494
495 default:
496 {
497 delete New;
498 }
499
500 }
501 m_Data->EndChange();
502 }
503
InitializeImages()504 void wxsItemEditor::InitializeImages()
505 {
506 if ( m_ImagesLoaded ) return;
507 wxString basePath = ConfigManager::GetDataFolder() + _T("/images/wxsmith/");
508
509 static const wxString NormalNames[] =
510 {
511 _T("insertpoint32.png"),
512 _T("insertinto32.png"),
513 _T("insertafter32.png"),
514 _T("insertbefore32.png"),
515 _T("deletewidget32.png"),
516 _T("showpreview32.png"),
517 _T("quickpropsopen32.png"),
518 _T("quickpropsclose32.png"),
519 _T("selected32.png")
520 };
521
522 static const wxString SmallNames[] =
523 {
524 _T("insertpoint16.png"),
525 _T("insertinto16.png"),
526 _T("insertafter16.png"),
527 _T("insertbefore16.png"),
528 _T("deletewidget16.png"),
529 _T("showpreview16.png"),
530 _T("quickpropsopen16.png"),
531 _T("quickpropsclose16.png"),
532 _T("selected16.png")
533 };
534
535 const wxString* Array = ( ToolIconSize() == 16L ) ? SmallNames : NormalNames;
536
537 m_InsPointImg.LoadFile(basePath + Array[0]);
538 m_InsIntoImg.LoadFile(basePath + Array[1]);
539 m_InsAfterImg.LoadFile(basePath + Array[2]);
540 m_InsBeforeImg.LoadFile(basePath + Array[3]);
541 m_DelImg.LoadFile(basePath + Array[4]);
542 m_PreviewImg.LoadFile(basePath + Array[5]);
543 m_QuickPropsImgOpen.LoadFile(basePath + Array[6]);
544 m_QuickPropsImgClose.LoadFile(basePath + Array[7]);
545 m_SelectedImg.LoadFile(basePath + Array[8]);
546
547 m_ImagesLoaded = true;
548 }
549
OnButton(wxCommandEvent & event)550 void wxsItemEditor::OnButton(wxCommandEvent& event)
551 {
552 wxWindow* Btn = (wxWindow*)event.GetEventObject();
553 if ( Btn )
554 {
555 InsertRequest(Btn->GetName());
556 }
557 }
558
SetInsertionTypeMask(int Mask)559 void wxsItemEditor::SetInsertionTypeMask(int Mask)
560 {
561 m_InsTypeMask = Mask;
562 SetInsertionType(m_InsType);
563 }
564
SetInsertionType(int Type)565 void wxsItemEditor::SetInsertionType(int Type)
566 {
567 Type &= m_InsTypeMask;
568
569 if ( !Type )
570 {
571 Type = m_InsTypeMask;
572 }
573
574 if ( Type & itPoint )
575 {
576 m_InsType = itPoint;
577 }
578 else if ( Type & itInto )
579 {
580 m_InsType = itInto;
581 }
582 else if ( Type & itAfter )
583 {
584 m_InsType = itAfter;
585 }
586 else if ( Type & itBefore )
587 {
588 m_InsType = itBefore;
589 }
590 else
591 {
592 m_InsType = 0;
593 }
594
595 RebuildInsTypeIcons();
596 }
597
RebuildInsTypeIcons()598 void wxsItemEditor::RebuildInsTypeIcons()
599 {
600 BuildInsTypeIcon(m_InsPointBtn,m_InsPointImg,itPoint);
601 BuildInsTypeIcon(m_InsIntoBtn,m_InsIntoImg,itInto);
602 BuildInsTypeIcon(m_InsBeforeBtn,m_InsBeforeImg,itBefore);
603 BuildInsTypeIcon(m_InsAfterBtn,m_InsAfterImg,itAfter);
604 }
605
BuildInsTypeIcon(wxBitmapButton * Btn,const wxImage & Original,int ButtonType)606 void wxsItemEditor::BuildInsTypeIcon(wxBitmapButton* Btn,const wxImage& Original,int ButtonType)
607 {
608 bool Selected = (m_InsType & ButtonType) != 0;
609 bool Enabled = (m_InsTypeMask & ButtonType) != 0;
610
611 if ( !Enabled || !Selected )
612 {
613 Btn->SetBitmapLabel(Original);
614 }
615 else
616 {
617 wxBitmap Copy = Original;
618 wxMemoryDC DC;
619 DC.SelectObject(Copy);
620 DC.DrawBitmap(m_SelectedImg,0,0);
621 Btn->SetBitmapLabel(Copy);
622 }
623
624 Btn->Enable(Enabled);
625 Btn->Refresh();
626 }
627
RebuildQuickPropsIcon()628 void wxsItemEditor::RebuildQuickPropsIcon()
629 {
630 m_QuickPanelBtn->SetBitmapLabel( m_QuickPropsOpen ? m_QuickPropsImgClose : m_QuickPropsImgOpen );
631 }
632
RebuildIcons()633 void wxsItemEditor::RebuildIcons()
634 {
635 RebuildInsTypeIcons();
636 RebuildQuickPropsIcon();
637 m_DelBtn->SetBitmapLabel(m_DelImg);
638 m_PreviewBtn->SetBitmapLabel(m_PreviewImg);
639 BuildPalette(m_WidgetsSet);
640 Layout();
641 }
642
643 namespace
644 {
PrioritySort(const wxsItemInfo ** it1,const wxsItemInfo ** it2)645 int PrioritySort(const wxsItemInfo** it1,const wxsItemInfo** it2)
646 {
647 return (*it1)->Priority - (*it2)->Priority;
648 }
649
650 WX_DEFINE_ARRAY(const wxsItemInfo*,ItemsT);
651
CategorySort(ItemsT * it1,ItemsT * it2)652 int CategorySort(ItemsT* it1, ItemsT* it2)
653 {
654 if (it1->Item(0)->Category.IsSameAs(_T("Standard")))
655 return -1;
656
657 if (it2->Item(0)->Category.IsSameAs(_T("Standard")))
658 return 1;
659
660 return wxStrcmp(it1->Item(0)->Category, it2->Item(0)->Category);
661 }
662
663 WX_DECLARE_STRING_HASH_MAP(ItemsT,MapT);
664 WX_DEFINE_SORTED_ARRAY(ItemsT*,ArrayOfItemsT);
665 }
666
BuildPalette(wxNotebook * Palette)667 void wxsItemEditor::BuildPalette(wxNotebook* Palette)
668 {
669 Palette->DeleteAllPages();
670 bool AllowNonXRCItems = (m_Data->GetPropertiesFilter() & flSource);
671
672 // First we need to split all widgets into groups
673 // it will be done using multimap (map of arrays)
674
675 MapT Map;
676 ArrayOfItemsT aoi(CategorySort);
677
678 for ( const wxsItemInfo* Info = wxsItemFactory::GetFirstInfo(); Info; Info = wxsItemFactory::GetNextInfo() )
679 {
680 if ( !Info->Category.empty() )
681 {
682 Map[Info->Category].Add(Info);
683 }
684 }
685
686 for ( MapT::iterator i = Map.begin(); i!=Map.end(); ++i )
687 {
688 aoi.Add(&(i->second));
689 }
690 for (size_t i = 0; i < aoi.Count(); ++i)
691 {
692 ItemsT* Items = aoi.Item(i);
693 Items->Sort(PrioritySort);
694 wxScrolledWindow* CurrentPanel = new wxScrolledWindow(Palette,-1,wxDefaultPosition,wxDefaultSize,0/*wxALWAYS_SHOW_SB|wxHSCROLL*/);
695 CurrentPanel->SetScrollRate(1,0);
696 Palette->AddPage(CurrentPanel,Items->Item(0)->Category);
697 wxSizer* RowSizer = new wxBoxSizer(wxHORIZONTAL);
698
699 for ( size_t j=Items->Count(); j-->0; )
700 {
701 const wxsItemInfo* Info = Items->Item(j);
702 const wxBitmap& Icon = ( PalIconSize() == 16L ) ? Info->Icon16 : Info->Icon32;
703
704 if ( AllowNonXRCItems || Info->AllowInXRC )
705 {
706 wxWindow* Btn;
707 if ( Icon.Ok() )
708 {
709 Btn = new wxBitmapButton(CurrentPanel,-1,Icon,
710 wxDefaultPosition,wxDefaultSize,wxBU_AUTODRAW,
711 wxDefaultValidator, Info->ClassName);
712 RowSizer->Add(Btn,0,wxALIGN_CENTER);
713 }
714 else
715 {
716 Btn = new wxButton(CurrentPanel,-1,Info->ClassName,
717 wxDefaultPosition,wxDefaultSize,0,
718 wxDefaultValidator,Info->ClassName);
719 RowSizer->Add(Btn,0,wxGROW);
720 }
721 Btn->SetToolTip(Info->ClassName);
722 }
723 }
724 CurrentPanel->SetSizer(RowSizer);
725 #if wxCHECK_VERSION(3, 0, 0)
726 RowSizer->FitInside(CurrentPanel);
727 #else
728 RowSizer->SetVirtualSizeHints(CurrentPanel);
729 #endif
730 }
731 }
732
OnInsPoint(cb_unused wxCommandEvent & event)733 void wxsItemEditor::OnInsPoint(cb_unused wxCommandEvent& event)
734 {
735 SetInsertionType(itPoint);
736 }
737
OnInsInto(cb_unused wxCommandEvent & event)738 void wxsItemEditor::OnInsInto(cb_unused wxCommandEvent& event)
739 {
740 SetInsertionType(itInto);
741 }
742
OnInsAfter(cb_unused wxCommandEvent & event)743 void wxsItemEditor::OnInsAfter(cb_unused wxCommandEvent& event)
744 {
745 SetInsertionType(itAfter);
746 }
747
OnInsBefore(cb_unused wxCommandEvent & event)748 void wxsItemEditor::OnInsBefore(cb_unused wxCommandEvent& event)
749 {
750 SetInsertionType(itBefore);
751 }
752
OnDelete(cb_unused wxCommandEvent & event)753 void wxsItemEditor::OnDelete(cb_unused wxCommandEvent& event)
754 {
755 if ( !m_Data ) return;
756 m_Data->BeginChange();
757 m_Data->DeleteSelected();
758 m_Data->EndChange();
759 }
760
OnPreview(cb_unused wxCommandEvent & event)761 void wxsItemEditor::OnPreview(cb_unused wxCommandEvent& event)
762 {
763 if ( !m_Data ) return;
764
765 m_Content->BlockFetch(true);
766
767 if ( m_Data->IsPreview() )
768 {
769 m_Data->HidePreview();
770 }
771 else
772 {
773 m_Data->ShowPreview();
774 }
775
776 m_Content->BlockFetch(false);
777 }
778
OnQuickProps(cb_unused wxCommandEvent & event)779 void wxsItemEditor::OnQuickProps(cb_unused wxCommandEvent& event)
780 {
781 m_QuickPropsOpen = !m_QuickPropsOpen;
782 RebuildQuickPropsIcon();
783 ToggleQuickPropsPanel(m_QuickPropsOpen);
784 }
785
ToggleQuickPropsPanel(bool Open)786 void wxsItemEditor::ToggleQuickPropsPanel(bool Open)
787 {
788 m_HorizSizer->Show(m_QPArea,Open,true);
789 Layout();
790 }
791
RebuildQuickProps(wxsItem * Selection)792 void wxsItemEditor::RebuildQuickProps(wxsItem* Selection)
793 {
794 // Checking if we've already initialized visual stuff
795 if ( !m_Content ) return;
796
797 Freeze();
798
799 int QPx, QPy;
800 // TODO: Check if content of previous QPPanel shouldn't be stored into item
801 m_QPArea->GetViewStart(&QPx,&QPy);
802 m_QPArea->SetSizer(0);
803 m_QPArea->DestroyChildren();
804 m_QPSizer = new wxBoxSizer(wxVERTICAL);
805 m_QPArea->SetSizer(m_QPSizer);
806
807 if ( Selection )
808 {
809 wxWindow* QPPanel = Selection->BuildQuickPropertiesPanel(m_QPArea);
810 if ( QPPanel )
811 {
812 m_QPSizer->Add(QPPanel,0,wxEXPAND);
813 }
814 }
815 m_QPSizer->Layout();
816 m_QPSizer->Fit(m_QPArea);
817 Layout();
818 m_QPArea->Scroll(QPx,QPy);
819 Thaw();
820 }
821
GetReferenceItem(int & InsertionType)822 wxsItem* wxsItemEditor::GetReferenceItem(int& InsertionType)
823 {
824 wxsItem* Reference = m_Data->GetLastSelection();
825 if ( !Reference )
826 {
827 // Fixing up reference item when there's nothing selected
828 InsertionType = itInto;
829 Reference = m_Data->GetRootItem();
830 wxsParent* AsParent = Reference->ConvertToParent();
831 if ( AsParent &&
832 AsParent->GetChildCount() == 1 &&
833 AsParent->GetChild(0)->GetType() == wxsTSizer )
834 {
835 Reference = AsParent->GetChild(0);
836 }
837 }
838 return Reference;
839 }
840
OnKeyDown(wxKeyEvent & event)841 void wxsItemEditor::OnKeyDown(wxKeyEvent& event)
842 {
843 switch ( event.GetKeyCode() )
844 {
845 case WXK_DELETE:
846 if ( !m_Data ) break;
847 m_Data->BeginChange();
848 m_Data->DeleteSelected();
849 m_Data->EndChange();
850 break;
851
852 default:
853 break;
854 }
855 }
856
StartInsertPointSequence(const wxsItemInfo * Info)857 void wxsItemEditor::StartInsertPointSequence(const wxsItemInfo* Info)
858 {
859 if ( m_Content )
860 {
861 m_Content->InsertByPointing(Info);
862 }
863 }
864
ShowPopup(wxsItem * Item,wxMenu * Popup)865 void wxsItemEditor::ShowPopup(wxsItem* Item,wxMenu* Popup)
866 {
867 m_PopupCaller = Item;
868 PopupMenu(Popup);
869 }
870
OnPopup(wxCommandEvent & event)871 void wxsItemEditor::OnPopup(wxCommandEvent& event)
872 {
873 if ( m_PopupCaller )
874 {
875 if ( !m_PopupCaller->PopupMenu(event.GetId()) )
876 {
877 event.Skip();
878 }
879 }
880 }
881
882 wxImage wxsItemEditor::m_InsPointImg;
883 wxImage wxsItemEditor::m_InsIntoImg;
884 wxImage wxsItemEditor::m_InsBeforeImg;
885 wxImage wxsItemEditor::m_InsAfterImg;
886 wxImage wxsItemEditor::m_DelImg;
887 wxImage wxsItemEditor::m_PreviewImg;
888 wxImage wxsItemEditor::m_QuickPropsImgOpen;
889 wxImage wxsItemEditor::m_QuickPropsImgClose;
890 wxImage wxsItemEditor::m_SelectedImg;
891 wxsItemEditor::WindowSet wxsItemEditor::m_AllEditors;
892 bool wxsItemEditor::m_ImagesLoaded = false;
893
894 BEGIN_EVENT_TABLE(wxsItemEditor,wxsEditor)
895 EVT_BUTTON(wxsInsPointId,wxsItemEditor::OnInsPoint)
896 EVT_BUTTON(wxsInsIntoId,wxsItemEditor::OnInsInto)
897 EVT_BUTTON(wxsInsBeforeId,wxsItemEditor::OnInsBefore)
898 EVT_BUTTON(wxsInsAfterId,wxsItemEditor::OnInsAfter)
899 EVT_BUTTON(wxsDelId,wxsItemEditor::OnDelete)
900 EVT_BUTTON(wxsPreviewId,wxsItemEditor::OnPreview)
901 EVT_BUTTON(wxsQuickPropsId,wxsItemEditor::OnQuickProps)
902 EVT_BUTTON(-1,wxsItemEditor::OnButton)
903 EVT_KEY_DOWN(wxsItemEditor::OnKeyDown)
904 EVT_MENU(wxID_ANY,wxsItemEditor::OnPopup)
905 END_EVENT_TABLE()
906