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 "creawxVTKRenderWindowInteractor.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 #define GIMMICK_NO_IMAGE_SELECTION 0
39 #define GIMMICK_2D_IMAGE_SELECTION 2
40 #define GIMMICK_3D_IMAGE_SELECTION 3
41 #define GIMMICK_4D_IMAGE_SELECTION 4
43 //====================================================================
44 class CREAIMAGEIO_EXPORT WxGimmick : public wxPanel,
45 public MultiThreadImageReaderUser
49 WxGimmick(wxWindow *parent, const wxWindowID id,
50 const wxPoint& pos, const wxSize& size,
51 int image_type = GIMMICK_3D_IMAGE_SELECTION,
52 int number_of_threads = 0);
56 int GetSelectionSize() { return mTreeListCtrl->GetSelectionSize(); }
57 bool IsSelectionValid();
58 void GetSelectedFiles(std::vector<std::string>&);
59 void GetSelectedImages(std::vector<vtkImageData*>&);
60 void GetSelectedDicomNodes(std::vector<DicomNode*>&);
61 void GetSelectedItems(std::vector<wxTreeItemId>&);
62 DicomNode* GetDicomNodeOfItem(const wxTreeItemId& i);
64 static const int UserMenuFirstId;
66 typedef WxGimmickSettings Settings;
67 const Settings& GetSettings() const { return mSettings; }
68 Settings& GetSettings() { return mSettings; }
70 typedef WxGimmickEvent EventType;
72 typedef std::vector<DicomDatabase*> DicomDatabaseListType;
74 DicomDatabaseListType& GetDicomDatabaseList()
75 { return mDicomDatabaseList; }
76 const DicomDatabaseListType& GetDicomDatabaseList() const
77 { return mDicomDatabaseList; }
79 wxTreeListCtrl* GetTreeListCtrl() { return mTreeListCtrl; }
80 const wxTreeListCtrl* GetTreeListCtrl() const { return mTreeListCtrl; }
82 void SetConfigurationFile(const std::string& filename)
83 { mConfigurationFile = filename;}
84 void LoadConfiguration();
85 void SaveConfiguration();
86 void SetSaveConfigurationOnClose(bool v)
87 { mSaveConfigurationOnClose = v; }
93 void UpdateDicomDatabaseView(DicomDatabase*);
94 void UpdateDicomNodeView(DicomNode* n, const wxTreeItemId& parent);
95 void DeleteObsoleteChildren(wxTreeItemId& id);
96 wxTreeItemId CreateChildrenColumnsTitles(wxTreeItemId& item,
98 void UpdateColumnsTitles(wxTreeItemId& item, DicomNode::Type t);
99 void UpdateColumns(wxTreeItemId& item, bool only_first = false);
100 void OpenOrNewDatabase(bool open);
102 void InsertDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
103 void DeleteDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
105 void LoadChildren( wxTreeItemId& id );
106 friend class WxGimmickEvent;
111 WxGimmick(const WxGimmick& ) { }
114 int mSelectionMaxImageDimension;
115 int mCurrentSelectionImageSize[4];
117 DicomDatabaseListType mDicomDatabaseList;
119 wxTreeListCtrl* mTreeListCtrl;
120 wxTreeItemId mTreeRootId;
121 wxTreeItemId mCollectionsTitlesItemId;
123 std::string mUserSettingsDirectory;
124 void CreateUserSettingsDirectory();
125 const std::string& GetUserSettingsDirectory();
126 wxString mCurrentDirectory;
127 std::string mConfigurationFile;
128 std::string mDatabaseListFile;
129 bool mSaveConfigurationOnClose;
131 std::string mDatabaseExtension;
132 const std::string& GetDatabaseExtension() { return mDatabaseExtension; }
133 void SetDatabaseExtension(const std::string& ext)
134 { mDatabaseExtension = ext; }
137 int mFirstDicomDatabaseIconIndex;
138 // Id of the item which activated the popup menu
139 wxTreeItemId mItemOfMenu;
142 /// Preview related stuff
144 wxPanel *mPanelImage;
146 WxGimmickFieldsView* mFieldsView;
148 wxSplitterWindow *mSplitter1;
149 wxSplitterWindow *mSplitter2;
151 void ShowImage(vtkImageData* image);
152 void ShowInformation(DicomNode*);
154 vtkImageViewer2* mViewer;
155 // Associated wxvtk interactor
156 crea::creawxVTKRenderWindowInteractor *mInteractor;
158 int mx1,mx2,my1,my2,mz1,mz2;
159 double mspx,mspy,mspz;
162 // Multi-thread image reader
163 MultiThreadImageReader mReader;
164 // map of images name to node
165 std::map<std::string,DicomNode*> mImageFileNameToNode;
166 // Cur image item to show
167 wxTreeItemId mCurImageItemToShow;
168 // type of image event
169 // If the image pointer is non null then the image is available (loaded)
170 // else it has been unloaded
171 struct ImageEventType
173 ImageEventType( wxTreeItemId it, vtkImageData* im )
174 : item(it), image(im) {}
175 ImageEventType(vtkImageData* im )
180 // queue of image event
181 typedef std::deque<ImageEventType> ImageEventQueueType;
182 ImageEventQueueType mImageEventQueue;
183 // Processes the queue of image events
184 // Called in OnInternalIdle();
185 // (locks the MultiThreadImageReaderEvent mutex)
186 void ProcessImageEvents();
188 void OnInternalIdle();
190 typedef WxGimmickTreeItemData TreeItemData;
191 TreeItemData* GetItemData(const wxTreeItemId& id)
192 { return (TreeItemData *)mTreeListCtrl->GetItemData(id); }
194 typedef WxGimmickDicomNodeData NodeData;
199 // void OnClose(wxCloseEvent& event);
200 void OnBeginDrag(wxTreeEvent& event);
201 void OnBeginRDrag(wxTreeEvent& event);
202 void OnEndDrag(wxTreeEvent& event);
203 void OnBeginLabelEdit(wxTreeEvent& event);
204 void OnEndLabelEdit(wxTreeEvent& event);
205 void OnDeleteItem(wxTreeEvent& event);
207 void OnGetInfo(wxTreeEvent& event);
208 void OnSetInfo(wxTreeEvent& event);
209 void OnItemExpanded(wxTreeEvent& event);
210 void OnItemExpanding(wxTreeEvent& event);
211 void OnItemCollapsed(wxTreeEvent& event);
212 void OnItemCollapsing(wxTreeEvent& event);
213 void OnSelChanged(wxTreeEvent& event);
214 void OnSelChanging(wxTreeEvent& event);
215 bool IsImageSelectable(DicomNode* node);
216 void OnTreeKeyDown(wxTreeEvent& event);
217 void OnItemActivated(wxTreeEvent& event);
218 void OnItemRightClick(wxTreeEvent& event);
220 // Pop up menu callbacks
221 void ShowMenu(wxTreeItemId id, const wxPoint& pt);
222 void OnPopUpNewCollection(wxCommandEvent& event);
223 void OnPopUpOpenCollection(wxCommandEvent& event);
224 void OnPopUpCloseCollection(wxCommandEvent& event);
225 void OnPopUpDeleteCollection(wxCommandEvent& event);
226 void OnPopUpAddFile(wxCommandEvent& event);
227 void OnPopUpAddRawFile(wxCommandEvent& event);
228 void OnPopUpAddDirectory(wxCommandEvent& event);
229 void OnPopUpRemove(wxCommandEvent& event);
230 void OnPopUpSettings(wxCommandEvent& event);
231 void OnPopUpAbout(wxCommandEvent& event);
232 void OnPopUpUser(wxCommandEvent& event);
233 void OnPopUpSort(wxCommandEvent& event);
235 void CreateImageList(int size = 16);
236 void CreateButtonsImageList(int size = 11);
238 // Multi-thread image reader callback
239 void OnMultiThreadImageReaderEvent(const std::string& filename,
240 MultiThreadImageReaderUser::EventType t,
241 vtkImageData* image);
243 void DoSortChildren(const wxTreeItemId& item, bool reverse = false)
244 { m_reverseSort = reverse; wxTreeListCtrl::SortChildren(item); }
245 void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); }
248 void DoToggleIcon(const wxTreeItemId& item);
251 int ImageSize(void) const { return m_imageSize; }
253 // void SetLastItem(wxTreeItemId id) { m_lastItem = id; }
256 // virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
262 // void LogEvent(const wxChar *name, const wxTreeEvent& event);
264 int m_imageSize; // current size of images
267 bool m_reverseSort; // flag for OnCompareItems
268 wxTreeItemId m_lastItem, // for OnEnsureVisible()
269 m_draggedItem; // item being dragged right now
271 // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS()
272 // if you want your overloaded OnCompareItems() to be called.
273 // OTOH, if you don't want it you may omit the next line - this will
274 // make default (alphabetical) sorting much faster under wxMSW.
275 // DECLARE_DYNAMIC_CLASS(wxTree)
276 DECLARE_EVENT_TABLE()
278 //====================================================================
287 //====================================================================
288 class CREAIMAGEIO_EXPORT WxGimmickEvent : public wxNotifyEvent
291 WxGimmickEvent(wxEventType commandType,
293 const wxTreeItemId &item = wxTreeItemId());
295 WxGimmickEvent(wxEventType commandType = wxEVT_NULL, int id = 0);
296 WxGimmickEvent(const WxGimmickEvent& event);
298 virtual wxEvent *Clone() const { return new WxGimmickEvent(*this); }
301 // get the item on which the operation was performed or the newly
302 // selected item for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events
303 wxTreeItemId GetItem() const { return m_item; }
304 void SetItem(const wxTreeItemId& item) { m_item = item; }
306 // for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events, get the previously
308 wxTreeItemId GetOldItem() const { return m_itemOld; }
309 void SetOldItem(const wxTreeItemId& item) { m_itemOld = item; }
311 // the point where the mouse was when the drag operation started (for
312 // wxEVT_COMMAND_TREE_BEGIN_(R)DRAG events only) or click position
313 // wxPoint GetPoint() const { return m_pointDrag; }
314 // void SetPoint(const wxPoint& pt) { m_pointDrag = pt; }
316 // keyboard data (for wxEVT_COMMAND_TREE_KEY_DOWN only)
317 const wxKeyEvent& GetKeyEvent() const { return m_evtKey; }
318 int GetKeyCode() const { return m_evtKey.GetKeyCode(); }
319 void SetKeyEvent(const wxKeyEvent& evt) { m_evtKey = evt; }
321 void SetDicomNode(DicomNode* n) { mDicomNode = n; }
322 DicomNode* GetDicomNode() { return mDicomNode; }
324 wxMenu& GetMenu() { return *m_PopUpMenu; }
325 void SetMenu(wxMenu* m) { m_PopUpMenu = m; }
327 void SetColor(wxColor& c) { mColor=c; }
328 wxColor& GetColor() { return mColor; }
330 void* GetUserData() const { return mUserData; }
331 void SetUserData(void* v) { mUserData = v; }
333 // label (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
334 // const wxString& GetLabel() const { return m_label; }
335 // void SetLabel(const wxString& label) { m_label = label; }
337 // edit cancel flag (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
338 // bool IsEditCancelled() const { return m_editCancelled; }
339 // void SetEditCanceled(bool editCancelled) { m_editCancelled = editCancelled; }
341 // Set the tooltip for the item (for EVT\_TREE\_ITEM\_GETTOOLTIP events)
342 // void SetToolTip(const wxString& toolTip) { m_label = toolTip; }
343 // wxString GetToolTip() { return m_label; }
346 // not all of the members are used (or initialized) for all events
351 DicomNode* mDicomNode;
354 // wxPoint m_pointDrag;
356 // bool m_editCancelled;
358 friend class /*WXDLLEXPORT*/ WxGimmick;
359 // friend class WXDLLEXPORT wxGenericTreeListCtrl;
361 DECLARE_DYNAMIC_CLASS(WxGimmickEvent)
363 //====================================================================
365 typedef void (wxEvtHandler::*WxGimmickEventFunction)(WxGimmickEvent&);
367 // ----------------------------------------------------------------------------
368 // tree control events and macros for handling them
369 // ----------------------------------------------------------------------------
371 BEGIN_DECLARE_EVENT_TYPES()
372 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_DRAG, 600)
373 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_RDRAG, 601)
374 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_LABEL_EDIT, 602)
375 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_LABEL_EDIT, 603)
376 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_DELETE_ITEM, 604)
377 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_GET_INFO, 605)
378 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_SET_INFO, 606)
379 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDED, 607)
380 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDING, 608)
381 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSED, 609)
382 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSING, 610)
383 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGED, 666611)
384 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGING, 666612)
385 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_KEY_DOWN, 666613)
386 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_CONTEXTUAL_MENU, 666614)
387 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_ITEM_STYLE_CHANGED, 666615)
388 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_ACTIVATED, 614)
389 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_RIGHT_CLICK, 615)
390 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MIDDLE_CLICK, 616)
391 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_DRAG, 617)
392 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_STATE_IMAGE_CLICK, 618)
393 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_GETTOOLTIP, 619)
394 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MENU, 620)
395 END_DECLARE_EVENT_TYPES()
397 #define WxGimmickEventHandler(func) \
398 (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(WxGimmickEventFunction, &func)
400 #define wx__DECLARE_TREEVIEWLISTEVT(evt, id, fn) \
401 wx__DECLARE_EVT1(wxEVT_COMMAND_TREEVIEWLIST_ ## evt, id, WxGimmickEventHandler(fn))
403 // GetItem() returns the item being dragged, GetPoint() the mouse coords
405 // if you call event.Allow(), the drag operation will start and a
406 // EVT_TREEVIEW_END_DRAG event will be sent when the drag is over.
407 //#define EVT_TREEVIEW_BEGIN_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_DRAG, id, fn)
408 //#define EVT_TREEVIEW_BEGIN_RDRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_RDRAG, id, fn)
410 // GetItem() is the item on which the drop occurred (if any) and GetPoint() the
411 // current mouse coords
412 //#define EVT_TREEVIEW_END_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(END_DRAG, id, fn)
414 // GetItem() returns the itme whose label is being edited, GetLabel() returns
415 // the current item label for BEGIN and the would be new one for END.
417 // Vetoing BEGIN event means that label editing won't happen at all,
418 // vetoing END means that the new value is discarded and the old one kept
419 //#define EVT_TREEVIEW_BEGIN_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_LABEL_EDIT, id, fn)
420 //#define EVT_TREEVIEW_END_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(END_LABEL_EDIT, id, fn)
422 // provide/update information about GetItem() item
423 //#define EVT_TREEVIEW_GET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(GET_INFO, id, fn)
424 //#define EVT_TREEVIEW_SET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(SET_INFO, id, fn)
426 // GetItem() is the item being expanded/collapsed, the "ING" versions can use
427 //#define EVT_TREEVIEW_ITEM_EXPANDED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDED, id, fn)
428 //#define EVT_TREEVIEW_ITEM_EXPANDING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDING, id, fn)
429 //#define EVT_TREEVIEW_ITEM_COLLAPSED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSED, id, fn)
430 //#define EVT_TREEVIEW_ITEM_COLLAPSING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSING, id, fn)
432 // GetOldItem() is the item which had the selection previously, GetItem() is
433 // the item which acquires selection
434 #define EVT_TREEVIEWLIST_SEL_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGED, id, fn)
435 #define EVT_TREEVIEWLIST_SEL_CHANGING(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGING, id, fn)
437 // GetKeyCode() returns the key code
438 // NB: this is the only message for which GetItem() is invalid (you may get the
439 // item from GetSelection())
440 #define EVT_TREEVIEWLIST_KEY_DOWN(id, fn) wx__DECLARE_TREEVIEWLISTEVT(KEY_DOWN, id, fn)
441 #define EVT_TREEVIEWLIST_CONTEXTUAL_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(CONTEXTUAL_MENU, id, fn)
442 #define EVT_TREEVIEWLIST_ITEM_STYLE_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_STYLE_CHANGED, id, fn)
444 // GetItem() returns the item being deleted, the associated data (if any) will
445 // be deleted just after the return of this event handler (if any)
446 //#define EVT_TREEVIEWLIST_DELETE_ITEM(id, fn) wx__DECLARE_TREEVIEWLISTEVT(DELETE_ITEM, id, fn)
448 // GetItem() returns the item that was activated (double click, enter, space)
449 //#define EVT_TREEVIEWLIST_ITEM_ACTIVATED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_ACTIVATED, id, fn)
451 // GetItem() returns the item for which the context menu shall be shown
452 //#define EVT_TREEVIEWLIST_ITEM_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MENU, id, fn)
454 // GetItem() returns the item that was clicked on
455 //#define EVT_TREEVIEWLIST_ITEM_RIGHT_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_RIGHT_CLICK, id, fn)
456 //#define EVT_TREEVIEWLIST_ITEM_MIDDLE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MIDDLE_CLICK, id, fn)
458 // GetItem() returns the item whose state image was clicked on
459 //#define EVT_TREEVIEWLIST_STATE_IMAGE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(STATE_IMAGE_CLICK, id, fn)
461 // GetItem() is the item for which the tooltip is being requested
462 //#define EVT_TREEVIEWLIST_ITEM_GETTOOLTIP(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_GETTOOLTIP, id, fn)
469 //====================================================================
470 class WxGimmickFrame : public wxFrame
473 WxGimmickFrame( wxWindow *parent, wxString title, wxSize size);
476 WxGimmick* GetWxGimmick() { return mWxGimmick; }
478 void OnSelChanged(WxGimmickEvent& event);
481 DECLARE_EVENT_TABLE();
484 WxGimmick* mWxGimmick;
486 //====================================================================
490 } // namespace creaImageIO
493 #endif // #ifndef __creaImageIOWxGimmick_h_INCLUDED__