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 <wx/notebook.h>
14 #include "treelistctrl.h"
16 // dicom fields view panel
17 #include <creaImageIOWxGimmickFieldsView.h>
19 #include <creaImageIOWxGimmickSettings.h>
22 // vtk and wxvtk classes
23 #include "creawxVTKRenderWindowInteractor.h"
24 #include "vtkImageViewer2.h"
25 // multi-thread image reader
26 #include <creaImageIOMultiThreadImageReader.h>
32 //====================================================================
33 // Forward decl of event class for WxGimmick
35 class WxGimmickTreeItemData;
36 class WxGimmickDicomNodeData;
37 //====================================================================
39 #define GIMMICK_NO_IMAGE_SELECTION 0
40 #define GIMMICK_2D_IMAGE_SELECTION 2
41 #define GIMMICK_3D_IMAGE_SELECTION 3
42 #define GIMMICK_4D_IMAGE_SELECTION 4
44 //====================================================================
45 class CREAIMAGEIO_EXPORT WxGimmick : public wxPanel,
46 public MultiThreadImageReaderUser
50 WxGimmick(wxWindow *parent, const wxWindowID id,
51 const wxPoint& pos, const wxSize& size,
52 int image_type = GIMMICK_3D_IMAGE_SELECTION,
53 int number_of_threads = 0);
57 int GetSelectionSize() { return mTreeListCtrl->GetSelectionSize(); }
58 bool IsSelectionValid();
59 void GetSelectedFiles(std::vector<std::string>&);
60 void GetSelectedImages(std::vector<vtkImageData*>&);
61 void GetSelectedDicomNodes(std::vector<DicomNode*>&);
62 void GetSelectedItems(std::vector<wxTreeItemId>&);
63 DicomNode* GetDicomNodeOfItem(const wxTreeItemId& i);
65 static const int UserMenuFirstId;
67 typedef WxGimmickSettings Settings;
68 const Settings& GetSettings() const { return mSettings; }
69 Settings& GetSettings() { return mSettings; }
71 typedef WxGimmickEvent EventType;
73 typedef std::vector<DicomDatabase*> DicomDatabaseListType;
75 DicomDatabaseListType& GetDicomDatabaseList()
76 { return mDicomDatabaseList; }
77 const DicomDatabaseListType& GetDicomDatabaseList() const
78 { return mDicomDatabaseList; }
80 wxTreeListCtrl* GetTreeListCtrl() { return mTreeListCtrl; }
81 const wxTreeListCtrl* GetTreeListCtrl() const { return mTreeListCtrl; }
83 void SetConfigurationFile(const std::string& filename)
84 { mConfigurationFile = filename;}
85 void LoadConfiguration();
86 void SaveConfiguration();
87 void SetSaveConfigurationOnClose(bool v)
88 { mSaveConfigurationOnClose = v; }
94 void UpdateDicomDatabaseView(DicomDatabase*);
95 void UpdateDicomNodeView(DicomNode* n, const wxTreeItemId& parent);
96 void DeleteObsoleteChildren(wxTreeItemId& id);
97 wxTreeItemId CreateChildrenColumnsTitles(wxTreeItemId& item,
99 void UpdateColumnsTitles(wxTreeItemId& item, DicomNode::Type t);
100 void UpdateColumns(wxTreeItemId& item, bool only_first = false);
101 void OpenOrNewDatabase(bool open);
103 void InsertDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
104 void DeleteDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
106 void LoadChildren( wxTreeItemId& id );
107 friend class WxGimmickEvent;
114 WxGimmick(const WxGimmick& ) { }
117 int mSelectionMaxImageDimension;
118 int mCurrentSelectionImageSize[4];
120 DicomDatabaseListType mDicomDatabaseList;
122 wxTreeListCtrl* mTreeListCtrl;
123 wxTreeItemId mTreeRootId;
124 wxTreeItemId mCollectionsTitlesItemId;
126 std::string mUserSettingsDirectory;
127 void CreateUserSettingsDirectory();
128 const std::string& GetUserSettingsDirectory();
129 wxString mCurrentDirectory;
130 std::string mConfigurationFile;
131 std::string mDatabaseListFile;
132 bool mSaveConfigurationOnClose;
134 std::string mDatabaseExtension;
135 const std::string& GetDatabaseExtension() { return mDatabaseExtension; }
136 void SetDatabaseExtension(const std::string& ext)
137 { mDatabaseExtension = ext; }
145 WxGimmickHelp* mHelp;
148 int mFirstDicomDatabaseIconIndex;
149 // Id of the item which activated the popup menu
150 wxTreeItemId mItemOfMenu;
153 /// Preview related stuff
155 wxPanel *mPanelImage;
157 WxGimmickFieldsView* mFieldsView;
159 wxNotebook* mwxNotebook;
161 wxSplitterWindow *mSplitter1;
162 wxSplitterWindow *mSplitter2;
164 void ShowImage(vtkImageData* image);
165 void ShowInformation(DicomNode*);
167 vtkImageViewer2* mViewer;
168 // Associated wxvtk interactor
169 crea::creawxVTKRenderWindowInteractor *mInteractor;
171 int mx1,mx2,my1,my2,mz1,mz2;
172 double mspx,mspy,mspz;
175 // Multi-thread image reader
176 MultiThreadImageReader mReader;
177 // map of images name to node
178 std::map<std::string,DicomNode*> mImageFileNameToNode;
179 // Cur image item to show
180 wxTreeItemId mCurImageItemToShow;
181 // type of image event
182 // If the image pointer is non null then the image is available (loaded)
183 // else it has been unloaded
184 struct ImageEventType
186 ImageEventType( wxTreeItemId it, vtkImageData* im )
187 : item(it), image(im) {}
188 ImageEventType(vtkImageData* im )
193 // queue of image event
194 typedef std::deque<ImageEventType> ImageEventQueueType;
195 ImageEventQueueType mImageEventQueue;
196 // Processes the queue of image events
197 // Called in OnInternalIdle();
198 // (locks the MultiThreadImageReaderEvent mutex)
199 void ProcessImageEvents();
201 void OnInternalIdle();
203 typedef WxGimmickTreeItemData TreeItemData;
204 TreeItemData* GetItemData(const wxTreeItemId& id)
205 { return (TreeItemData *)mTreeListCtrl->GetItemData(id); }
207 typedef WxGimmickDicomNodeData NodeData;
212 // void OnClose(wxCloseEvent& event);
213 void OnBeginDrag(wxTreeEvent& event);
214 void OnBeginRDrag(wxTreeEvent& event);
215 void OnEndDrag(wxTreeEvent& event);
216 void OnBeginLabelEdit(wxTreeEvent& event);
217 void OnEndLabelEdit(wxTreeEvent& event);
218 void OnDeleteItem(wxTreeEvent& event);
220 void OnGetInfo(wxTreeEvent& event);
221 void OnSetInfo(wxTreeEvent& event);
222 void OnItemExpanded(wxTreeEvent& event);
223 void OnItemExpanding(wxTreeEvent& event);
224 void OnItemCollapsed(wxTreeEvent& event);
225 void OnItemCollapsing(wxTreeEvent& event);
226 void OnSelChanged(wxTreeEvent& event);
227 void OnSelChanging(wxTreeEvent& event);
228 bool IsImageSelectable(DicomNode* node);
229 void OnTreeKeyDown(wxTreeEvent& event);
230 void OnItemActivated(wxTreeEvent& event);
231 void OnItemRightClick(wxTreeEvent& event);
233 // Pop up menu callbacks
234 void ShowMenu(wxTreeItemId id, const wxPoint& pt);
235 void OnPopUpNewCollection(wxCommandEvent& event);
236 void OnPopUpOpenCollection(wxCommandEvent& event);
237 void OnPopUpCloseCollection(wxCommandEvent& event);
238 void OnPopUpDeleteCollection(wxCommandEvent& event);
239 void OnPopUpAddFile(wxCommandEvent& event);
240 void OnPopUpAddRawFile(wxCommandEvent& event);
241 void OnPopUpAddDirectory(wxCommandEvent& event);
242 void OnPopUpRemove(wxCommandEvent& event);
243 void OnPopUpSettings(wxCommandEvent& event);
244 void OnPopUpAbout(wxCommandEvent& event);
245 void OnPopUpUser(wxCommandEvent& event);
246 void OnPopUpSort(wxCommandEvent& event);
248 void CreateImageList(int size = 16);
249 void CreateButtonsImageList(int size = 11);
251 // Multi-thread image reader callback
252 void OnMultiThreadImageReaderEvent(const std::string& filename,
253 MultiThreadImageReaderUser::EventType t,
254 vtkImageData* image);
256 void DoSortChildren(const wxTreeItemId& item, bool reverse = false)
257 { m_reverseSort = reverse; wxTreeListCtrl::SortChildren(item); }
258 void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); }
261 void DoToggleIcon(const wxTreeItemId& item);
264 int ImageSize(void) const { return m_imageSize; }
266 // void SetLastItem(wxTreeItemId id) { m_lastItem = id; }
269 // virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
275 // void LogEvent(const wxChar *name, const wxTreeEvent& event);
277 int m_imageSize; // current size of images
280 bool m_reverseSort; // flag for OnCompareItems
281 wxTreeItemId m_lastItem, // for OnEnsureVisible()
282 m_draggedItem; // item being dragged right now
284 // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS()
285 // if you want your overloaded OnCompareItems() to be called.
286 // OTOH, if you don't want it you may omit the next line - this will
287 // make default (alphabetical) sorting much faster under wxMSW.
288 // DECLARE_DYNAMIC_CLASS(wxTree)
289 DECLARE_EVENT_TABLE()
291 //====================================================================
300 //====================================================================
301 class CREAIMAGEIO_EXPORT WxGimmickEvent : public wxNotifyEvent
304 WxGimmickEvent(wxEventType commandType,
306 const wxTreeItemId &item = wxTreeItemId());
308 WxGimmickEvent(wxEventType commandType = wxEVT_NULL, int id = 0);
309 WxGimmickEvent(const WxGimmickEvent& event);
311 virtual wxEvent *Clone() const { return new WxGimmickEvent(*this); }
314 // get the item on which the operation was performed or the newly
315 // selected item for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events
316 wxTreeItemId GetItem() const { return m_item; }
317 void SetItem(const wxTreeItemId& item) { m_item = item; }
319 // for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events, get the previously
321 wxTreeItemId GetOldItem() const { return m_itemOld; }
322 void SetOldItem(const wxTreeItemId& item) { m_itemOld = item; }
324 // the point where the mouse was when the drag operation started (for
325 // wxEVT_COMMAND_TREE_BEGIN_(R)DRAG events only) or click position
326 // wxPoint GetPoint() const { return m_pointDrag; }
327 // void SetPoint(const wxPoint& pt) { m_pointDrag = pt; }
329 // keyboard data (for wxEVT_COMMAND_TREE_KEY_DOWN only)
330 const wxKeyEvent& GetKeyEvent() const { return m_evtKey; }
331 int GetKeyCode() const { return m_evtKey.GetKeyCode(); }
332 void SetKeyEvent(const wxKeyEvent& evt) { m_evtKey = evt; }
334 void SetDicomNode(DicomNode* n) { mDicomNode = n; }
335 DicomNode* GetDicomNode() { return mDicomNode; }
337 wxMenu& GetMenu() { return *m_PopUpMenu; }
338 void SetMenu(wxMenu* m) { m_PopUpMenu = m; }
340 void SetColor(wxColor& c) { mColor=c; }
341 wxColor& GetColor() { return mColor; }
343 void* GetUserData() const { return mUserData; }
344 void SetUserData(void* v) { mUserData = v; }
346 // label (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
347 // const wxString& GetLabel() const { return m_label; }
348 // void SetLabel(const wxString& label) { m_label = label; }
350 // edit cancel flag (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
351 // bool IsEditCancelled() const { return m_editCancelled; }
352 // void SetEditCanceled(bool editCancelled) { m_editCancelled = editCancelled; }
354 // Set the tooltip for the item (for EVT\_TREE\_ITEM\_GETTOOLTIP events)
355 // void SetToolTip(const wxString& toolTip) { m_label = toolTip; }
356 // wxString GetToolTip() { return m_label; }
359 // not all of the members are used (or initialized) for all events
364 DicomNode* mDicomNode;
367 // wxPoint m_pointDrag;
369 // bool m_editCancelled;
371 friend class /*WXDLLEXPORT*/ WxGimmick;
372 // friend class WXDLLEXPORT wxGenericTreeListCtrl;
374 DECLARE_DYNAMIC_CLASS(WxGimmickEvent)
376 //====================================================================
378 typedef void (wxEvtHandler::*WxGimmickEventFunction)(WxGimmickEvent&);
380 // ----------------------------------------------------------------------------
381 // tree control events and macros for handling them
382 // ----------------------------------------------------------------------------
384 BEGIN_DECLARE_EVENT_TYPES()
385 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_DRAG, 600)
386 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_RDRAG, 601)
387 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_LABEL_EDIT, 602)
388 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_LABEL_EDIT, 603)
389 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_DELETE_ITEM, 604)
390 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_GET_INFO, 605)
391 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_SET_INFO, 606)
392 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDED, 607)
393 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDING, 608)
394 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSED, 609)
395 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSING, 610)
396 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGED, 666611)
397 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGING, 666612)
398 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_KEY_DOWN, 666613)
399 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_CONTEXTUAL_MENU, 666614)
400 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_ITEM_STYLE_CHANGED, 666615)
401 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_ACTIVATED, 614)
402 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_RIGHT_CLICK, 615)
403 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MIDDLE_CLICK, 616)
404 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_DRAG, 617)
405 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_STATE_IMAGE_CLICK, 618)
406 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_GETTOOLTIP, 619)
407 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MENU, 620)
408 END_DECLARE_EVENT_TYPES()
410 #define WxGimmickEventHandler(func) \
411 (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(WxGimmickEventFunction, &func)
413 #define wx__DECLARE_TREEVIEWLISTEVT(evt, id, fn) \
414 wx__DECLARE_EVT1(wxEVT_COMMAND_TREEVIEWLIST_ ## evt, id, WxGimmickEventHandler(fn))
416 // GetItem() returns the item being dragged, GetPoint() the mouse coords
418 // if you call event.Allow(), the drag operation will start and a
419 // EVT_TREEVIEW_END_DRAG event will be sent when the drag is over.
420 //#define EVT_TREEVIEW_BEGIN_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_DRAG, id, fn)
421 //#define EVT_TREEVIEW_BEGIN_RDRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_RDRAG, id, fn)
423 // GetItem() is the item on which the drop occurred (if any) and GetPoint() the
424 // current mouse coords
425 //#define EVT_TREEVIEW_END_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(END_DRAG, id, fn)
427 // GetItem() returns the itme whose label is being edited, GetLabel() returns
428 // the current item label for BEGIN and the would be new one for END.
430 // Vetoing BEGIN event means that label editing won't happen at all,
431 // vetoing END means that the new value is discarded and the old one kept
432 //#define EVT_TREEVIEW_BEGIN_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_LABEL_EDIT, id, fn)
433 //#define EVT_TREEVIEW_END_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(END_LABEL_EDIT, id, fn)
435 // provide/update information about GetItem() item
436 //#define EVT_TREEVIEW_GET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(GET_INFO, id, fn)
437 //#define EVT_TREEVIEW_SET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(SET_INFO, id, fn)
439 // GetItem() is the item being expanded/collapsed, the "ING" versions can use
440 //#define EVT_TREEVIEW_ITEM_EXPANDED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDED, id, fn)
441 //#define EVT_TREEVIEW_ITEM_EXPANDING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDING, id, fn)
442 //#define EVT_TREEVIEW_ITEM_COLLAPSED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSED, id, fn)
443 //#define EVT_TREEVIEW_ITEM_COLLAPSING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSING, id, fn)
445 // GetOldItem() is the item which had the selection previously, GetItem() is
446 // the item which acquires selection
447 #define EVT_TREEVIEWLIST_SEL_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGED, id, fn)
448 #define EVT_TREEVIEWLIST_SEL_CHANGING(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGING, id, fn)
450 // GetKeyCode() returns the key code
451 // NB: this is the only message for which GetItem() is invalid (you may get the
452 // item from GetSelection())
453 #define EVT_TREEVIEWLIST_KEY_DOWN(id, fn) wx__DECLARE_TREEVIEWLISTEVT(KEY_DOWN, id, fn)
454 #define EVT_TREEVIEWLIST_CONTEXTUAL_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(CONTEXTUAL_MENU, id, fn)
455 #define EVT_TREEVIEWLIST_ITEM_STYLE_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_STYLE_CHANGED, id, fn)
457 // GetItem() returns the item being deleted, the associated data (if any) will
458 // be deleted just after the return of this event handler (if any)
459 //#define EVT_TREEVIEWLIST_DELETE_ITEM(id, fn) wx__DECLARE_TREEVIEWLISTEVT(DELETE_ITEM, id, fn)
461 // GetItem() returns the item that was activated (double click, enter, space)
462 //#define EVT_TREEVIEWLIST_ITEM_ACTIVATED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_ACTIVATED, id, fn)
464 // GetItem() returns the item for which the context menu shall be shown
465 //#define EVT_TREEVIEWLIST_ITEM_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MENU, id, fn)
467 // GetItem() returns the item that was clicked on
468 //#define EVT_TREEVIEWLIST_ITEM_RIGHT_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_RIGHT_CLICK, id, fn)
469 //#define EVT_TREEVIEWLIST_ITEM_MIDDLE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MIDDLE_CLICK, id, fn)
471 // GetItem() returns the item whose state image was clicked on
472 //#define EVT_TREEVIEWLIST_STATE_IMAGE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(STATE_IMAGE_CLICK, id, fn)
474 // GetItem() is the item for which the tooltip is being requested
475 //#define EVT_TREEVIEWLIST_ITEM_GETTOOLTIP(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_GETTOOLTIP, id, fn)
482 //====================================================================
483 class WxGimmickFrame : public wxFrame
486 WxGimmickFrame( wxWindow *parent, wxString title, wxSize size);
489 WxGimmick* GetWxGimmick() { return mWxGimmick; }
491 void OnSelChanged(WxGimmickEvent& event);
494 DECLARE_EVENT_TABLE();
497 WxGimmick* mWxGimmick;
499 //====================================================================
503 } // namespace creaImageIO
506 #endif // #ifndef __creaImageIOWxGimmick_h_INCLUDED__