1 #ifndef __creaImageIOWxGimmick_h_INCLUDED__
2 #define __creaImageIOWxGimmick_h_INCLUDED__
5 #include <creaImageIOSystem.h>
6 #include <creaImageIODicomDatabase.h>
11 #include "wx/imaglist.h"
12 #include <wx/splitter.h>
13 #include "treelistctrl.h"
15 // dicom fields view panel
16 #include <creaImageIOWxGimmickFieldsView.h>
18 #include <creaImageIOWxGimmickSettings.h>
21 // vtk and wxvtk classes
22 #include "wxVTKRenderWindowInteractor.h"
23 #include "vtkImageViewer2.h"
24 // multi-thread image reader
25 #include <creaImageIOMultiThreadImageReader.h>
31 //====================================================================
32 // Forward decl of event class for WxGimmick
34 class WxGimmickTreeItemData;
35 class WxGimmickDicomNodeData;
36 //====================================================================
38 //====================================================================
39 class CREAIMAGEIO_EXPORT WxGimmick : public wxPanel,
40 public MultiThreadImageReaderUser
43 WxGimmick(wxWindow *parent, const wxWindowID id,
44 const wxPoint& pos, const wxSize& size,
45 int number_of_threads = 0);
49 typedef std::vector<DicomDatabase*> DicomDatabaseListType;
51 DicomDatabaseListType& GetDicomDatabaseList() { return mDicomDatabaseList; }
52 const DicomDatabaseListType& GetDicomDatabaseList() const { return mDicomDatabaseList; }
54 wxTreeListCtrl* GetTreeListCtrl() { return mTreeListCtrl; }
55 const wxTreeListCtrl* GetTreeListCtrl() const { return mTreeListCtrl; }
57 void SetConfigurationFile(const std::string& filename)
59 mConfigurationFile = filename;
61 void LoadConfiguration();
62 void SaveConfiguration();
63 void SetSaveConfigurationOnClose(bool v)
64 { mSaveConfigurationOnClose = v; }
67 void GetSelectedImages(std::vector<std::string>&);
68 void GetSelectedDicomNodes(std::vector<DicomNode*>&);
69 void GetSelectedItems(std::vector<wxTreeItemId>&);
70 DicomNode* GetDicomNodeOfItem(const wxTreeItemId& i);
73 static const int UserMenuFirstId;
75 typedef WxGimmickSettings Settings;
76 const Settings& GetSettings() const { return mSettings; }
77 Settings& GetSettings() { return mSettings; }
79 typedef WxGimmickEvent EventType;
83 void UpdateDicomDatabaseView(DicomDatabase*);
84 void UpdateDicomNodeView(DicomNode* n, const wxTreeItemId& parent);
85 void DeleteObsoleteChildren(wxTreeItemId& id);
86 wxTreeItemId CreateChildrenColumnsTitles(wxTreeItemId& item,
88 void UpdateColumnsTitles(wxTreeItemId& item, DicomNode::Type t);
89 void UpdateColumns(wxTreeItemId& item, bool only_first = false);
90 void OpenOrNewDatabase(bool open);
92 void InsertDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
93 void DeleteDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
95 friend class WxGimmickEvent;
100 WxGimmick(const WxGimmick& ) { }
102 DicomDatabaseListType mDicomDatabaseList;
104 wxTreeListCtrl* mTreeListCtrl;
105 wxTreeItemId mTreeRootId;
106 wxTreeItemId mCollectionsTitlesItemId;
108 std::string mUserSettingsDirectory;
109 void CreateUserSettingsDirectory();
110 const std::string& GetUserSettingsDirectory();
111 wxString mCurrentDirectory;
112 std::string mConfigurationFile;
113 std::string mDatabaseListFile;
114 bool mSaveConfigurationOnClose;
116 std::string mDatabaseExtension;
117 const std::string& GetDatabaseExtension() { return mDatabaseExtension; }
118 void SetDatabaseExtension(const std::string& ext)
119 { mDatabaseExtension = ext; }
122 int mFirstDicomDatabaseIconIndex;
123 // Id of the item which activated the popup menu
124 wxTreeItemId mItemOfMenu;
127 /// Preview related stuff
129 wxPanel *mPanelImage;
131 WxGimmickFieldsView* mFieldsView;
133 wxSplitterWindow *mSplitter1;
134 wxSplitterWindow *mSplitter2;
136 void ShowImage(vtkImageData* image);
137 void ShowInformation(DicomNode*);
139 vtkImageViewer2* mViewer;
140 // Associated wxvtk interactor
141 crea::wxVTKRenderWindowInteractor *mInteractor;
143 int mx1,mx2,my1,my2,mz1,mz2;
144 double mspx,mspy,mspz;
147 // Multi-thread image reader
148 MultiThreadImageReader mReader;
149 // map of images name to node
150 std::map<std::string,DicomNode*> mImageFileNameToNode;
151 // Cur image item to show
152 wxTreeItemId mCurImageItemToShow;
153 // type of image event
154 // If the image pointer is non null then the image is available (loaded)
155 // else it has been unloaded
156 struct ImageEventType
158 ImageEventType( wxTreeItemId it, vtkImageData* im )
159 : item(it), image(im) {}
160 ImageEventType(vtkImageData* im )
165 // queue of image event
166 typedef std::deque<ImageEventType> ImageEventQueueType;
167 ImageEventQueueType mImageEventQueue;
168 // Processes the queue of image events
169 // Called in OnInternalIdle();
170 // (locks the MultiThreadImageReaderEvent mutex)
171 void ProcessImageEvents();
173 void OnInternalIdle();
175 typedef WxGimmickTreeItemData TreeItemData;
176 TreeItemData* GetItemData(const wxTreeItemId& id)
177 { return (TreeItemData *)mTreeListCtrl->GetItemData(id); }
179 typedef WxGimmickDicomNodeData NodeData;
184 // void OnClose(wxCloseEvent& event);
185 void OnBeginDrag(wxTreeEvent& event);
186 void OnBeginRDrag(wxTreeEvent& event);
187 void OnEndDrag(wxTreeEvent& event);
188 void OnBeginLabelEdit(wxTreeEvent& event);
189 void OnEndLabelEdit(wxTreeEvent& event);
190 void OnDeleteItem(wxTreeEvent& event);
192 void OnGetInfo(wxTreeEvent& event);
193 void OnSetInfo(wxTreeEvent& event);
194 void OnItemExpanded(wxTreeEvent& event);
195 void OnItemExpanding(wxTreeEvent& event);
196 void OnItemCollapsed(wxTreeEvent& event);
197 void OnItemCollapsing(wxTreeEvent& event);
198 void OnSelChanged(wxTreeEvent& event);
199 void OnSelChanging(wxTreeEvent& event);
200 void OnTreeKeyDown(wxTreeEvent& event);
201 void OnItemActivated(wxTreeEvent& event);
202 void OnItemRightClick(wxTreeEvent& event);
204 // Pop up menu callbacks
205 void ShowMenu(wxTreeItemId id, const wxPoint& pt);
206 void OnPopUpNewCollection(wxCommandEvent& event);
207 void OnPopUpOpenCollection(wxCommandEvent& event);
208 void OnPopUpCloseCollection(wxCommandEvent& event);
209 void OnPopUpDeleteCollection(wxCommandEvent& event);
210 void OnPopUpAddFile(wxCommandEvent& event);
211 void OnPopUpAddRawFile(wxCommandEvent& event);
212 void OnPopUpAddDirectory(wxCommandEvent& event);
213 void OnPopUpRemove(wxCommandEvent& event);
214 void OnPopUpSettings(wxCommandEvent& event);
215 void OnPopUpAbout(wxCommandEvent& event);
216 void OnPopUpUser(wxCommandEvent& event);
217 void OnPopUpSort(wxCommandEvent& event);
219 void CreateImageList(int size = 16);
220 void CreateButtonsImageList(int size = 11);
222 // Multi-thread image reader callback
223 void OnMultiThreadImageReaderEvent(const std::string& filename,
224 MultiThreadImageReaderUser::EventType t,
225 vtkImageData* image);
227 void DoSortChildren(const wxTreeItemId& item, bool reverse = false)
228 { m_reverseSort = reverse; wxTreeListCtrl::SortChildren(item); }
229 void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); }
232 void DoToggleIcon(const wxTreeItemId& item);
235 int ImageSize(void) const { return m_imageSize; }
237 // void SetLastItem(wxTreeItemId id) { m_lastItem = id; }
240 // virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
246 // void LogEvent(const wxChar *name, const wxTreeEvent& event);
248 int m_imageSize; // current size of images
251 bool m_reverseSort; // flag for OnCompareItems
252 wxTreeItemId m_lastItem, // for OnEnsureVisible()
253 m_draggedItem; // item being dragged right now
255 // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS()
256 // if you want your overloaded OnCompareItems() to be called.
257 // OTOH, if you don't want it you may omit the next line - this will
258 // make default (alphabetical) sorting much faster under wxMSW.
259 // DECLARE_DYNAMIC_CLASS(wxTree)
260 DECLARE_EVENT_TABLE()
262 //====================================================================
271 //====================================================================
272 class CREAIMAGEIO_EXPORT WxGimmickEvent : public wxNotifyEvent
275 WxGimmickEvent(wxEventType commandType,
277 const wxTreeItemId &item = wxTreeItemId());
279 WxGimmickEvent(wxEventType commandType = wxEVT_NULL, int id = 0);
280 WxGimmickEvent(const WxGimmickEvent& event);
282 virtual wxEvent *Clone() const { return new WxGimmickEvent(*this); }
285 // get the item on which the operation was performed or the newly
286 // selected item for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events
287 wxTreeItemId GetItem() const { return m_item; }
288 void SetItem(const wxTreeItemId& item) { m_item = item; }
290 // for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events, get the previously
292 wxTreeItemId GetOldItem() const { return m_itemOld; }
293 void SetOldItem(const wxTreeItemId& item) { m_itemOld = item; }
295 // the point where the mouse was when the drag operation started (for
296 // wxEVT_COMMAND_TREE_BEGIN_(R)DRAG events only) or click position
297 // wxPoint GetPoint() const { return m_pointDrag; }
298 // void SetPoint(const wxPoint& pt) { m_pointDrag = pt; }
300 // keyboard data (for wxEVT_COMMAND_TREE_KEY_DOWN only)
301 const wxKeyEvent& GetKeyEvent() const { return m_evtKey; }
302 int GetKeyCode() const { return m_evtKey.GetKeyCode(); }
303 void SetKeyEvent(const wxKeyEvent& evt) { m_evtKey = evt; }
305 void SetDicomNode(DicomNode* n) { mDicomNode = n; }
306 DicomNode* GetDicomNode() { return mDicomNode; }
308 wxMenu& GetMenu() { return *m_PopUpMenu; }
309 void SetMenu(wxMenu* m) { m_PopUpMenu = m; }
311 void SetColor(wxColor& c) { mColor=c; }
312 wxColor& GetColor() { return mColor; }
314 void* GetUserData() const { return mUserData; }
315 void SetUserData(void* v) { mUserData = v; }
317 // label (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
318 // const wxString& GetLabel() const { return m_label; }
319 // void SetLabel(const wxString& label) { m_label = label; }
321 // edit cancel flag (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
322 // bool IsEditCancelled() const { return m_editCancelled; }
323 // void SetEditCanceled(bool editCancelled) { m_editCancelled = editCancelled; }
325 // Set the tooltip for the item (for EVT\_TREE\_ITEM\_GETTOOLTIP events)
326 // void SetToolTip(const wxString& toolTip) { m_label = toolTip; }
327 // wxString GetToolTip() { return m_label; }
330 // not all of the members are used (or initialized) for all events
335 DicomNode* mDicomNode;
338 // wxPoint m_pointDrag;
340 // bool m_editCancelled;
342 friend class /*WXDLLEXPORT*/ WxGimmick;
343 // friend class WXDLLEXPORT wxGenericTreeListCtrl;
345 DECLARE_DYNAMIC_CLASS(WxGimmickEvent)
347 //====================================================================
349 typedef void (wxEvtHandler::*WxGimmickEventFunction)(WxGimmickEvent&);
351 // ----------------------------------------------------------------------------
352 // tree control events and macros for handling them
353 // ----------------------------------------------------------------------------
355 BEGIN_DECLARE_EVENT_TYPES()
356 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_DRAG, 600)
357 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_RDRAG, 601)
358 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_LABEL_EDIT, 602)
359 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_LABEL_EDIT, 603)
360 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_DELETE_ITEM, 604)
361 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_GET_INFO, 605)
362 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_SET_INFO, 606)
363 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDED, 607)
364 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDING, 608)
365 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSED, 609)
366 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSING, 610)
367 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGED, 666611)
368 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGING, 666612)
369 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_KEY_DOWN, 666613)
370 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_CONTEXTUAL_MENU, 666614)
371 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_ITEM_STYLE_CHANGED, 666615)
372 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_ACTIVATED, 614)
373 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_RIGHT_CLICK, 615)
374 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MIDDLE_CLICK, 616)
375 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_DRAG, 617)
376 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_STATE_IMAGE_CLICK, 618)
377 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_GETTOOLTIP, 619)
378 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MENU, 620)
379 END_DECLARE_EVENT_TYPES()
381 #define WxGimmickEventHandler(func) \
382 (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(WxGimmickEventFunction, &func)
384 #define wx__DECLARE_TREEVIEWLISTEVT(evt, id, fn) \
385 wx__DECLARE_EVT1(wxEVT_COMMAND_TREEVIEWLIST_ ## evt, id, WxGimmickEventHandler(fn))
387 // GetItem() returns the item being dragged, GetPoint() the mouse coords
389 // if you call event.Allow(), the drag operation will start and a
390 // EVT_TREEVIEW_END_DRAG event will be sent when the drag is over.
391 //#define EVT_TREEVIEW_BEGIN_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_DRAG, id, fn)
392 //#define EVT_TREEVIEW_BEGIN_RDRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_RDRAG, id, fn)
394 // GetItem() is the item on which the drop occurred (if any) and GetPoint() the
395 // current mouse coords
396 //#define EVT_TREEVIEW_END_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(END_DRAG, id, fn)
398 // GetItem() returns the itme whose label is being edited, GetLabel() returns
399 // the current item label for BEGIN and the would be new one for END.
401 // Vetoing BEGIN event means that label editing won't happen at all,
402 // vetoing END means that the new value is discarded and the old one kept
403 //#define EVT_TREEVIEW_BEGIN_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_LABEL_EDIT, id, fn)
404 //#define EVT_TREEVIEW_END_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(END_LABEL_EDIT, id, fn)
406 // provide/update information about GetItem() item
407 //#define EVT_TREEVIEW_GET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(GET_INFO, id, fn)
408 //#define EVT_TREEVIEW_SET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(SET_INFO, id, fn)
410 // GetItem() is the item being expanded/collapsed, the "ING" versions can use
411 //#define EVT_TREEVIEW_ITEM_EXPANDED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDED, id, fn)
412 //#define EVT_TREEVIEW_ITEM_EXPANDING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDING, id, fn)
413 //#define EVT_TREEVIEW_ITEM_COLLAPSED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSED, id, fn)
414 //#define EVT_TREEVIEW_ITEM_COLLAPSING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSING, id, fn)
416 // GetOldItem() is the item which had the selection previously, GetItem() is
417 // the item which acquires selection
418 #define EVT_TREEVIEWLIST_SEL_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGED, id, fn)
419 #define EVT_TREEVIEWLIST_SEL_CHANGING(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGING, id, fn)
421 // GetKeyCode() returns the key code
422 // NB: this is the only message for which GetItem() is invalid (you may get the
423 // item from GetSelection())
424 #define EVT_TREEVIEWLIST_KEY_DOWN(id, fn) wx__DECLARE_TREEVIEWLISTEVT(KEY_DOWN, id, fn)
425 #define EVT_TREEVIEWLIST_CONTEXTUAL_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(CONTEXTUAL_MENU, id, fn)
426 #define EVT_TREEVIEWLIST_ITEM_STYLE_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_STYLE_CHANGED, id, fn)
428 // GetItem() returns the item being deleted, the associated data (if any) will
429 // be deleted just after the return of this event handler (if any)
430 //#define EVT_TREEVIEWLIST_DELETE_ITEM(id, fn) wx__DECLARE_TREEVIEWLISTEVT(DELETE_ITEM, id, fn)
432 // GetItem() returns the item that was activated (double click, enter, space)
433 //#define EVT_TREEVIEWLIST_ITEM_ACTIVATED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_ACTIVATED, id, fn)
435 // GetItem() returns the item for which the context menu shall be shown
436 //#define EVT_TREEVIEWLIST_ITEM_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MENU, id, fn)
438 // GetItem() returns the item that was clicked on
439 //#define EVT_TREEVIEWLIST_ITEM_RIGHT_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_RIGHT_CLICK, id, fn)
440 //#define EVT_TREEVIEWLIST_ITEM_MIDDLE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MIDDLE_CLICK, id, fn)
442 // GetItem() returns the item whose state image was clicked on
443 //#define EVT_TREEVIEWLIST_STATE_IMAGE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(STATE_IMAGE_CLICK, id, fn)
445 // GetItem() is the item for which the tooltip is being requested
446 //#define EVT_TREEVIEWLIST_ITEM_GETTOOLTIP(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_GETTOOLTIP, id, fn)
453 //====================================================================
454 class WxGimmickFrame : public wxFrame
457 WxGimmickFrame( wxWindow *parent, wxString title, wxSize size);
460 WxGimmick* GetWxGimmick() { return mWxGimmick; }
462 void OnSelChanged(WxGimmickEvent& event);
465 DECLARE_EVENT_TABLE();
468 WxGimmick* mWxGimmick;
470 //====================================================================
474 } // namespace creaImageIO
477 #endif // #ifndef __creaImageIOWxGimmick_h_INCLUDED__