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 /// Returns the size of the current selection
58 int GetSelectionSize() { return mTreeListCtrl->GetSelectionSize(); }
59 /// Returns true if there is a valid selection
60 bool IsSelectionValid();
61 /// Returns the vector of full filenames of selected images
62 void GetSelectedFiles(std::vector<std::string>&);
63 /// Returns the vector of images corresponding to selection
64 void GetSelectedImages(std::vector<vtkImageData*>&);
65 /// Returns the vector of DicomNode corresponding to selection
66 void GetSelectedDicomNodes(std::vector<DicomNode*>&);
67 /// Returns the vector of wxTreeItemId corresponding to selection
68 void GetSelectedItems(std::vector<wxTreeItemId>&);
70 /// Returns the DicomNode corresponding to the tree item
71 DicomNode* GetDicomNodeOfItem(const wxTreeItemId& i);
73 /// Stores the first id of user menu
74 static const int UserMenuFirstId;
76 /// The class storing WxGimmick settings
77 typedef WxGimmickSettings Settings;
78 /// Returns the settings (const)
79 const Settings& GetSettings() const { return mSettings; }
80 /// Returns the settings
81 Settings& GetSettings() { return mSettings; }
84 /// The type of event sent by WxGimmick
85 typedef WxGimmickEvent EventType;
87 /// The type of list of DicomDatabase
88 typedef std::vector<DicomDatabase*> DicomDatabaseListType;
90 /// Returns the list of DicomDatabase open
91 DicomDatabaseListType& GetDicomDatabaseList()
92 { return mDicomDatabaseList; }
93 /// Returns the list of DicomDatabase open (const)
94 const DicomDatabaseListType& GetDicomDatabaseList() const
95 { return mDicomDatabaseList; }
97 /// Returns the wxTreeListCtrl of the main view
98 wxTreeListCtrl* GetTreeListCtrl() { return mTreeListCtrl; }
99 /// Returns the wxTreeListCtrl of the main view (const)
100 const wxTreeListCtrl* GetTreeListCtrl() const { return mTreeListCtrl; }
103 void SetConfigurationFile(const std::string& filename)
104 { mConfigurationFile = filename;}
105 void LoadConfiguration();
106 void SaveConfiguration();
107 void SetSaveConfigurationOnClose(bool v)
108 { mSaveConfigurationOnClose = v; }
109 void LoadOrCreateFavoritesDatabase();
114 /// Completely rebuilds the view (i.e. the wxTreeListCtrl) with
115 /// current DicomDatabaseList
117 /// Recursively updates the part of the view corresponding
118 /// to the DicomDatabase passed
119 /// i.e. creates items for the DicomNode which do not have
120 /// deletes obsolete items (whose DicomNode has been deleted)
121 void UpdateDicomDatabaseView(DicomDatabase*);
122 /// Recursively updates the part of the view corresponding
123 /// to the DicomNode provided.
124 /// parent is its parent in the tree (where to insert / remove it)
125 void UpdateDicomNodeView(DicomNode* n, const wxTreeItemId& parent);
126 /// Recursively deletes
127 void DeleteObsoleteChildren(wxTreeItemId& id);
128 /// Create the column titles of the children of the item
129 wxTreeItemId CreateChildrenColumnsTitles(wxTreeItemId& item,
132 void UpdateColumnsTitles(wxTreeItemId& item, DicomNode::Type t);
134 void UpdateColumns(wxTreeItemId& item, bool only_first = false);
138 /// General entry point for
139 void OpenOrNewDatabase(bool open);
141 void InsertDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
142 void DeleteDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
144 void LoadChildren( wxTreeItemId& id );
145 friend class WxGimmickEvent;
152 WxGimmick(const WxGimmick& ) { }
155 int mSelectionMaxImageDimension;
156 int mCurrentSelectionImageSize[4];
158 DicomDatabaseListType mDicomDatabaseList;
159 DicomDatabase* mFavoriteDatabase;
161 wxTreeListCtrl* mTreeListCtrl;
162 wxTreeItemId mTreeRootId;
163 wxTreeItemId mCollectionsTitlesItemId;
165 std::string mUserSettingsDirectory;
166 void CreateUserSettingsDirectory();
167 const std::string& GetUserSettingsDirectory();
168 wxString mCurrentDirectory;
169 std::string mConfigurationFile;
170 std::string mDatabaseListFile;
171 bool mSaveConfigurationOnClose;
173 std::string mDatabaseExtension;
174 const std::string& GetDatabaseExtension() { return mDatabaseExtension; }
175 void SetDatabaseExtension(const std::string& ext)
176 { mDatabaseExtension = ext; }
184 WxGimmickHelp* mHelp;
187 int mFirstDicomDatabaseIconIndex;
188 // Id of the item which activated the popup menu
189 wxTreeItemId mItemOfMenu;
192 /// Preview related stuff
194 wxPanel *mPanelImage;
196 WxGimmickFieldsView* mFieldsView;
198 wxNotebook* mwxNotebook;
200 wxSplitterWindow *mSplitter1;
201 wxSplitterWindow *mSplitter2;
203 void ShowImage(vtkImageData* image);
204 void ShowInformation(DicomNode*);
206 vtkImageViewer2* mViewer;
207 // Associated wxvtk interactor
208 crea::creawxVTKRenderWindowInteractor *mInteractor;
210 int mx1,mx2,my1,my2,mz1,mz2;
211 double mspx,mspy,mspz;
214 // Multi-thread image reader
215 MultiThreadImageReader mReader;
216 // map of images name to node
217 std::map<std::string,DicomNode*> mImageFileNameToNode;
218 // Cur image item to show
219 wxTreeItemId mCurImageItemToShow;
220 // type of image event
221 // If the image pointer is non null then the image is available (loaded)
222 // else it has been unloaded
223 struct ImageEventType
225 ImageEventType( wxTreeItemId it, vtkImageData* im )
226 : item(it), image(im) {}
227 ImageEventType(vtkImageData* im )
232 // queue of image event
233 typedef std::deque<ImageEventType> ImageEventQueueType;
234 ImageEventQueueType mImageEventQueue;
235 // Processes the queue of image events
236 // Called in OnInternalIdle();
237 // (locks the MultiThreadImageReaderEvent mutex)
238 void ProcessImageEvents();
240 void OnInternalIdle();
242 typedef WxGimmickTreeItemData TreeItemData;
243 TreeItemData* GetItemData(const wxTreeItemId& id)
244 { return (TreeItemData *)mTreeListCtrl->GetItemData(id); }
246 typedef WxGimmickDicomNodeData NodeData;
251 // void OnClose(wxCloseEvent& event);
252 void OnBeginDrag(wxTreeEvent& event);
253 void OnBeginRDrag(wxTreeEvent& event);
254 void OnEndDrag(wxTreeEvent& event);
255 void OnBeginLabelEdit(wxTreeEvent& event);
256 void OnEndLabelEdit(wxTreeEvent& event);
257 void OnDeleteItem(wxTreeEvent& event);
259 void OnGetInfo(wxTreeEvent& event);
260 void OnSetInfo(wxTreeEvent& event);
261 void OnItemExpanded(wxTreeEvent& event);
262 void OnItemExpanding(wxTreeEvent& event);
263 void OnItemCollapsed(wxTreeEvent& event);
264 void OnItemCollapsing(wxTreeEvent& event);
265 void OnSelChanged(wxTreeEvent& event);
266 void OnSelChanging(wxTreeEvent& event);
267 bool IsImageSelectable(DicomNode* node);
268 void OnTreeKeyDown(wxTreeEvent& event);
269 void OnItemActivated(wxTreeEvent& event);
270 void OnItemRightClick(wxTreeEvent& event);
272 // Pop up menu callbacks
273 void ShowMenu(wxTreeItemId id, const wxPoint& pt);
274 void OnPopUpNewCollection(wxCommandEvent& event);
275 void OnPopUpOpenCollection(wxCommandEvent& event);
276 void OnPopUpCloseCollection(wxCommandEvent& event);
277 void OnPopUpDeleteCollection(wxCommandEvent& event);
278 void OnPopUpAddFile(wxCommandEvent& event);
279 void OnPopUpAddRawFile(wxCommandEvent& event);
280 void OnPopUpAddDirectory(wxCommandEvent& event);
281 void OnPopUpAddToFavorites(wxCommandEvent& event);
282 void OnPopUpRemove(wxCommandEvent& event);
283 void OnPopUpSettings(wxCommandEvent& event);
284 void OnPopUpAbout(wxCommandEvent& event);
285 void OnPopUpUser(wxCommandEvent& event);
286 void OnPopUpSort(wxCommandEvent& event);
288 void CreateImageList(int size = 16);
289 void CreateButtonsImageList(int size = 11);
291 // Multi-thread image reader callback
292 void OnMultiThreadImageReaderEvent(const std::string& filename,
293 MultiThreadImageReaderUser::EventType t,
294 vtkImageData* image);
296 void DoSortChildren(const wxTreeItemId& item, bool reverse = false)
297 { m_reverseSort = reverse; wxTreeListCtrl::SortChildren(item); }
298 void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); }
301 void DoToggleIcon(const wxTreeItemId& item);
304 int ImageSize(void) const { return m_imageSize; }
306 // void SetLastItem(wxTreeItemId id) { m_lastItem = id; }
309 // virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
315 // void LogEvent(const wxChar *name, const wxTreeEvent& event);
317 int m_imageSize; // current size of images
320 bool m_reverseSort; // flag for OnCompareItems
321 wxTreeItemId m_lastItem, // for OnEnsureVisible()
322 m_draggedItem; // item being dragged right now
324 // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS()
325 // if you want your overloaded OnCompareItems() to be called.
326 // OTOH, if you don't want it you may omit the next line - this will
327 // make default (alphabetical) sorting much faster under wxMSW.
328 // DECLARE_DYNAMIC_CLASS(wxTree)
329 DECLARE_EVENT_TABLE()
331 //====================================================================
340 //====================================================================
341 class CREAIMAGEIO_EXPORT WxGimmickEvent : public wxNotifyEvent
344 WxGimmickEvent(wxEventType commandType,
346 const wxTreeItemId &item = wxTreeItemId());
348 WxGimmickEvent(wxEventType commandType = wxEVT_NULL, int id = 0);
349 WxGimmickEvent(const WxGimmickEvent& event);
351 virtual wxEvent *Clone() const { return new WxGimmickEvent(*this); }
354 // get the item on which the operation was performed or the newly
355 // selected item for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events
356 wxTreeItemId GetItem() const { return m_item; }
357 void SetItem(const wxTreeItemId& item) { m_item = item; }
359 // for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events, get the previously
361 wxTreeItemId GetOldItem() const { return m_itemOld; }
362 void SetOldItem(const wxTreeItemId& item) { m_itemOld = item; }
364 // the point where the mouse was when the drag operation started (for
365 // wxEVT_COMMAND_TREE_BEGIN_(R)DRAG events only) or click position
366 // wxPoint GetPoint() const { return m_pointDrag; }
367 // void SetPoint(const wxPoint& pt) { m_pointDrag = pt; }
369 // keyboard data (for wxEVT_COMMAND_TREE_KEY_DOWN only)
370 const wxKeyEvent& GetKeyEvent() const { return m_evtKey; }
371 int GetKeyCode() const { return m_evtKey.GetKeyCode(); }
372 void SetKeyEvent(const wxKeyEvent& evt) { m_evtKey = evt; }
374 void SetDicomNode(DicomNode* n) { mDicomNode = n; }
375 DicomNode* GetDicomNode() { return mDicomNode; }
377 wxMenu& GetMenu() { return *m_PopUpMenu; }
378 void SetMenu(wxMenu* m) { m_PopUpMenu = m; }
380 void SetColor(wxColor& c) { mColor=c; }
381 wxColor& GetColor() { return mColor; }
383 void* GetUserData() const { return mUserData; }
384 void SetUserData(void* v) { mUserData = v; }
386 // label (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
387 // const wxString& GetLabel() const { return m_label; }
388 // void SetLabel(const wxString& label) { m_label = label; }
390 // edit cancel flag (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
391 // bool IsEditCancelled() const { return m_editCancelled; }
392 // void SetEditCanceled(bool editCancelled) { m_editCancelled = editCancelled; }
394 // Set the tooltip for the item (for EVT\_TREE\_ITEM\_GETTOOLTIP events)
395 // void SetToolTip(const wxString& toolTip) { m_label = toolTip; }
396 // wxString GetToolTip() { return m_label; }
399 // not all of the members are used (or initialized) for all events
404 DicomNode* mDicomNode;
407 // wxPoint m_pointDrag;
409 // bool m_editCancelled;
411 friend class /*WXDLLEXPORT*/ WxGimmick;
412 // friend class WXDLLEXPORT wxGenericTreeListCtrl;
414 DECLARE_DYNAMIC_CLASS(WxGimmickEvent)
416 //====================================================================
418 typedef void (wxEvtHandler::*WxGimmickEventFunction)(WxGimmickEvent&);
420 // ----------------------------------------------------------------------------
421 // tree control events and macros for handling them
422 // ----------------------------------------------------------------------------
424 BEGIN_DECLARE_EVENT_TYPES()
425 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_DRAG, 600)
426 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_RDRAG, 601)
427 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_LABEL_EDIT, 602)
428 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_LABEL_EDIT, 603)
429 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_DELETE_ITEM, 604)
430 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_GET_INFO, 605)
431 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_SET_INFO, 606)
432 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDED, 607)
433 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDING, 608)
434 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSED, 609)
435 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSING, 610)
436 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGED, 666611)
437 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGING, 666612)
438 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_KEY_DOWN, 666613)
439 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_CONTEXTUAL_MENU, 666614)
440 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_ITEM_STYLE_CHANGED, 666615)
441 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_ACTIVATED, 614)
442 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_RIGHT_CLICK, 615)
443 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MIDDLE_CLICK, 616)
444 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_DRAG, 617)
445 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_STATE_IMAGE_CLICK, 618)
446 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_GETTOOLTIP, 619)
447 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MENU, 620)
448 END_DECLARE_EVENT_TYPES()
450 #define WxGimmickEventHandler(func) \
451 (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(WxGimmickEventFunction, &func)
453 #define wx__DECLARE_TREEVIEWLISTEVT(evt, id, fn) \
454 wx__DECLARE_EVT1(wxEVT_COMMAND_TREEVIEWLIST_ ## evt, id, WxGimmickEventHandler(fn))
456 // GetItem() returns the item being dragged, GetPoint() the mouse coords
458 // if you call event.Allow(), the drag operation will start and a
459 // EVT_TREEVIEW_END_DRAG event will be sent when the drag is over.
460 //#define EVT_TREEVIEW_BEGIN_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_DRAG, id, fn)
461 //#define EVT_TREEVIEW_BEGIN_RDRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_RDRAG, id, fn)
463 // GetItem() is the item on which the drop occurred (if any) and GetPoint() the
464 // current mouse coords
465 //#define EVT_TREEVIEW_END_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(END_DRAG, id, fn)
467 // GetItem() returns the itme whose label is being edited, GetLabel() returns
468 // the current item label for BEGIN and the would be new one for END.
470 // Vetoing BEGIN event means that label editing won't happen at all,
471 // vetoing END means that the new value is discarded and the old one kept
472 //#define EVT_TREEVIEW_BEGIN_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_LABEL_EDIT, id, fn)
473 //#define EVT_TREEVIEW_END_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(END_LABEL_EDIT, id, fn)
475 // provide/update information about GetItem() item
476 //#define EVT_TREEVIEW_GET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(GET_INFO, id, fn)
477 //#define EVT_TREEVIEW_SET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(SET_INFO, id, fn)
479 // GetItem() is the item being expanded/collapsed, the "ING" versions can use
480 //#define EVT_TREEVIEW_ITEM_EXPANDED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDED, id, fn)
481 //#define EVT_TREEVIEW_ITEM_EXPANDING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDING, id, fn)
482 //#define EVT_TREEVIEW_ITEM_COLLAPSED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSED, id, fn)
483 //#define EVT_TREEVIEW_ITEM_COLLAPSING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSING, id, fn)
485 // GetOldItem() is the item which had the selection previously, GetItem() is
486 // the item which acquires selection
487 #define EVT_TREEVIEWLIST_SEL_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGED, id, fn)
488 #define EVT_TREEVIEWLIST_SEL_CHANGING(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGING, id, fn)
490 // GetKeyCode() returns the key code
491 // NB: this is the only message for which GetItem() is invalid (you may get the
492 // item from GetSelection())
493 #define EVT_TREEVIEWLIST_KEY_DOWN(id, fn) wx__DECLARE_TREEVIEWLISTEVT(KEY_DOWN, id, fn)
494 #define EVT_TREEVIEWLIST_CONTEXTUAL_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(CONTEXTUAL_MENU, id, fn)
495 #define EVT_TREEVIEWLIST_ITEM_STYLE_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_STYLE_CHANGED, id, fn)
497 // GetItem() returns the item being deleted, the associated data (if any) will
498 // be deleted just after the return of this event handler (if any)
499 //#define EVT_TREEVIEWLIST_DELETE_ITEM(id, fn) wx__DECLARE_TREEVIEWLISTEVT(DELETE_ITEM, id, fn)
501 // GetItem() returns the item that was activated (double click, enter, space)
502 //#define EVT_TREEVIEWLIST_ITEM_ACTIVATED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_ACTIVATED, id, fn)
504 // GetItem() returns the item for which the context menu shall be shown
505 //#define EVT_TREEVIEWLIST_ITEM_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MENU, id, fn)
507 // GetItem() returns the item that was clicked on
508 //#define EVT_TREEVIEWLIST_ITEM_RIGHT_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_RIGHT_CLICK, id, fn)
509 //#define EVT_TREEVIEWLIST_ITEM_MIDDLE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MIDDLE_CLICK, id, fn)
511 // GetItem() returns the item whose state image was clicked on
512 //#define EVT_TREEVIEWLIST_STATE_IMAGE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(STATE_IMAGE_CLICK, id, fn)
514 // GetItem() is the item for which the tooltip is being requested
515 //#define EVT_TREEVIEWLIST_ITEM_GETTOOLTIP(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_GETTOOLTIP, id, fn)
522 //====================================================================
523 class WxGimmickFrame : public wxFrame
526 WxGimmickFrame( wxWindow *parent, wxString title, wxSize size);
529 WxGimmick* GetWxGimmick() { return mWxGimmick; }
531 void OnSelChanged(WxGimmickEvent& event);
534 DECLARE_EVENT_TABLE();
537 WxGimmick* mWxGimmick;
539 //====================================================================
543 } // namespace creaImageIO
546 #endif // #ifndef __creaImageIOWxGimmick_h_INCLUDED__