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;
113 WxGimmick(const WxGimmick& ) { }
116 int mSelectionMaxImageDimension;
117 int mCurrentSelectionImageSize[4];
119 DicomDatabaseListType mDicomDatabaseList;
121 wxTreeListCtrl* mTreeListCtrl;
122 wxTreeItemId mTreeRootId;
123 wxTreeItemId mCollectionsTitlesItemId;
125 std::string mUserSettingsDirectory;
126 void CreateUserSettingsDirectory();
127 const std::string& GetUserSettingsDirectory();
128 wxString mCurrentDirectory;
129 std::string mConfigurationFile;
130 std::string mDatabaseListFile;
131 bool mSaveConfigurationOnClose;
133 std::string mDatabaseExtension;
134 const std::string& GetDatabaseExtension() { return mDatabaseExtension; }
135 void SetDatabaseExtension(const std::string& ext)
136 { mDatabaseExtension = ext; }
144 WxGimmickHelpWindow* mHelpWindow;
147 int mFirstDicomDatabaseIconIndex;
148 // Id of the item which activated the popup menu
149 wxTreeItemId mItemOfMenu;
152 /// Preview related stuff
154 wxPanel *mPanelImage;
156 WxGimmickFieldsView* mFieldsView;
158 wxSplitterWindow *mSplitter1;
159 wxSplitterWindow *mSplitter2;
161 void ShowImage(vtkImageData* image);
162 void ShowInformation(DicomNode*);
164 vtkImageViewer2* mViewer;
165 // Associated wxvtk interactor
166 crea::creawxVTKRenderWindowInteractor *mInteractor;
168 int mx1,mx2,my1,my2,mz1,mz2;
169 double mspx,mspy,mspz;
172 // Multi-thread image reader
173 MultiThreadImageReader mReader;
174 // map of images name to node
175 std::map<std::string,DicomNode*> mImageFileNameToNode;
176 // Cur image item to show
177 wxTreeItemId mCurImageItemToShow;
178 // type of image event
179 // If the image pointer is non null then the image is available (loaded)
180 // else it has been unloaded
181 struct ImageEventType
183 ImageEventType( wxTreeItemId it, vtkImageData* im )
184 : item(it), image(im) {}
185 ImageEventType(vtkImageData* im )
190 // queue of image event
191 typedef std::deque<ImageEventType> ImageEventQueueType;
192 ImageEventQueueType mImageEventQueue;
193 // Processes the queue of image events
194 // Called in OnInternalIdle();
195 // (locks the MultiThreadImageReaderEvent mutex)
196 void ProcessImageEvents();
198 void OnInternalIdle();
200 typedef WxGimmickTreeItemData TreeItemData;
201 TreeItemData* GetItemData(const wxTreeItemId& id)
202 { return (TreeItemData *)mTreeListCtrl->GetItemData(id); }
204 typedef WxGimmickDicomNodeData NodeData;
209 // void OnClose(wxCloseEvent& event);
210 void OnBeginDrag(wxTreeEvent& event);
211 void OnBeginRDrag(wxTreeEvent& event);
212 void OnEndDrag(wxTreeEvent& event);
213 void OnBeginLabelEdit(wxTreeEvent& event);
214 void OnEndLabelEdit(wxTreeEvent& event);
215 void OnDeleteItem(wxTreeEvent& event);
217 void OnGetInfo(wxTreeEvent& event);
218 void OnSetInfo(wxTreeEvent& event);
219 void OnItemExpanded(wxTreeEvent& event);
220 void OnItemExpanding(wxTreeEvent& event);
221 void OnItemCollapsed(wxTreeEvent& event);
222 void OnItemCollapsing(wxTreeEvent& event);
223 void OnSelChanged(wxTreeEvent& event);
224 void OnSelChanging(wxTreeEvent& event);
225 bool IsImageSelectable(DicomNode* node);
226 void OnTreeKeyDown(wxTreeEvent& event);
227 void OnItemActivated(wxTreeEvent& event);
228 void OnItemRightClick(wxTreeEvent& event);
230 // Pop up menu callbacks
231 void ShowMenu(wxTreeItemId id, const wxPoint& pt);
232 void OnPopUpNewCollection(wxCommandEvent& event);
233 void OnPopUpOpenCollection(wxCommandEvent& event);
234 void OnPopUpCloseCollection(wxCommandEvent& event);
235 void OnPopUpDeleteCollection(wxCommandEvent& event);
236 void OnPopUpAddFile(wxCommandEvent& event);
237 void OnPopUpAddRawFile(wxCommandEvent& event);
238 void OnPopUpAddDirectory(wxCommandEvent& event);
239 void OnPopUpRemove(wxCommandEvent& event);
240 void OnPopUpSettings(wxCommandEvent& event);
241 void OnPopUpAbout(wxCommandEvent& event);
242 void OnPopUpUser(wxCommandEvent& event);
243 void OnPopUpSort(wxCommandEvent& event);
245 void CreateImageList(int size = 16);
246 void CreateButtonsImageList(int size = 11);
248 // Multi-thread image reader callback
249 void OnMultiThreadImageReaderEvent(const std::string& filename,
250 MultiThreadImageReaderUser::EventType t,
251 vtkImageData* image);
253 void DoSortChildren(const wxTreeItemId& item, bool reverse = false)
254 { m_reverseSort = reverse; wxTreeListCtrl::SortChildren(item); }
255 void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); }
258 void DoToggleIcon(const wxTreeItemId& item);
261 int ImageSize(void) const { return m_imageSize; }
263 // void SetLastItem(wxTreeItemId id) { m_lastItem = id; }
266 // virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
272 // void LogEvent(const wxChar *name, const wxTreeEvent& event);
274 int m_imageSize; // current size of images
277 bool m_reverseSort; // flag for OnCompareItems
278 wxTreeItemId m_lastItem, // for OnEnsureVisible()
279 m_draggedItem; // item being dragged right now
281 // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS()
282 // if you want your overloaded OnCompareItems() to be called.
283 // OTOH, if you don't want it you may omit the next line - this will
284 // make default (alphabetical) sorting much faster under wxMSW.
285 // DECLARE_DYNAMIC_CLASS(wxTree)
286 DECLARE_EVENT_TABLE()
288 //====================================================================
297 //====================================================================
298 class CREAIMAGEIO_EXPORT WxGimmickEvent : public wxNotifyEvent
301 WxGimmickEvent(wxEventType commandType,
303 const wxTreeItemId &item = wxTreeItemId());
305 WxGimmickEvent(wxEventType commandType = wxEVT_NULL, int id = 0);
306 WxGimmickEvent(const WxGimmickEvent& event);
308 virtual wxEvent *Clone() const { return new WxGimmickEvent(*this); }
311 // get the item on which the operation was performed or the newly
312 // selected item for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events
313 wxTreeItemId GetItem() const { return m_item; }
314 void SetItem(const wxTreeItemId& item) { m_item = item; }
316 // for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events, get the previously
318 wxTreeItemId GetOldItem() const { return m_itemOld; }
319 void SetOldItem(const wxTreeItemId& item) { m_itemOld = item; }
321 // the point where the mouse was when the drag operation started (for
322 // wxEVT_COMMAND_TREE_BEGIN_(R)DRAG events only) or click position
323 // wxPoint GetPoint() const { return m_pointDrag; }
324 // void SetPoint(const wxPoint& pt) { m_pointDrag = pt; }
326 // keyboard data (for wxEVT_COMMAND_TREE_KEY_DOWN only)
327 const wxKeyEvent& GetKeyEvent() const { return m_evtKey; }
328 int GetKeyCode() const { return m_evtKey.GetKeyCode(); }
329 void SetKeyEvent(const wxKeyEvent& evt) { m_evtKey = evt; }
331 void SetDicomNode(DicomNode* n) { mDicomNode = n; }
332 DicomNode* GetDicomNode() { return mDicomNode; }
334 wxMenu& GetMenu() { return *m_PopUpMenu; }
335 void SetMenu(wxMenu* m) { m_PopUpMenu = m; }
337 void SetColor(wxColor& c) { mColor=c; }
338 wxColor& GetColor() { return mColor; }
340 void* GetUserData() const { return mUserData; }
341 void SetUserData(void* v) { mUserData = v; }
343 // label (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
344 // const wxString& GetLabel() const { return m_label; }
345 // void SetLabel(const wxString& label) { m_label = label; }
347 // edit cancel flag (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only)
348 // bool IsEditCancelled() const { return m_editCancelled; }
349 // void SetEditCanceled(bool editCancelled) { m_editCancelled = editCancelled; }
351 // Set the tooltip for the item (for EVT\_TREE\_ITEM\_GETTOOLTIP events)
352 // void SetToolTip(const wxString& toolTip) { m_label = toolTip; }
353 // wxString GetToolTip() { return m_label; }
356 // not all of the members are used (or initialized) for all events
361 DicomNode* mDicomNode;
364 // wxPoint m_pointDrag;
366 // bool m_editCancelled;
368 friend class /*WXDLLEXPORT*/ WxGimmick;
369 // friend class WXDLLEXPORT wxGenericTreeListCtrl;
371 DECLARE_DYNAMIC_CLASS(WxGimmickEvent)
373 //====================================================================
375 typedef void (wxEvtHandler::*WxGimmickEventFunction)(WxGimmickEvent&);
377 // ----------------------------------------------------------------------------
378 // tree control events and macros for handling them
379 // ----------------------------------------------------------------------------
381 BEGIN_DECLARE_EVENT_TYPES()
382 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_DRAG, 600)
383 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_RDRAG, 601)
384 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_LABEL_EDIT, 602)
385 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_LABEL_EDIT, 603)
386 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_DELETE_ITEM, 604)
387 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_GET_INFO, 605)
388 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_SET_INFO, 606)
389 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDED, 607)
390 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDING, 608)
391 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSED, 609)
392 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSING, 610)
393 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGED, 666611)
394 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGING, 666612)
395 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_KEY_DOWN, 666613)
396 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_CONTEXTUAL_MENU, 666614)
397 DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_ITEM_STYLE_CHANGED, 666615)
398 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_ACTIVATED, 614)
399 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_RIGHT_CLICK, 615)
400 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MIDDLE_CLICK, 616)
401 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_DRAG, 617)
402 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_STATE_IMAGE_CLICK, 618)
403 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_GETTOOLTIP, 619)
404 // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MENU, 620)
405 END_DECLARE_EVENT_TYPES()
407 #define WxGimmickEventHandler(func) \
408 (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(WxGimmickEventFunction, &func)
410 #define wx__DECLARE_TREEVIEWLISTEVT(evt, id, fn) \
411 wx__DECLARE_EVT1(wxEVT_COMMAND_TREEVIEWLIST_ ## evt, id, WxGimmickEventHandler(fn))
413 // GetItem() returns the item being dragged, GetPoint() the mouse coords
415 // if you call event.Allow(), the drag operation will start and a
416 // EVT_TREEVIEW_END_DRAG event will be sent when the drag is over.
417 //#define EVT_TREEVIEW_BEGIN_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_DRAG, id, fn)
418 //#define EVT_TREEVIEW_BEGIN_RDRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_RDRAG, id, fn)
420 // GetItem() is the item on which the drop occurred (if any) and GetPoint() the
421 // current mouse coords
422 //#define EVT_TREEVIEW_END_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(END_DRAG, id, fn)
424 // GetItem() returns the itme whose label is being edited, GetLabel() returns
425 // the current item label for BEGIN and the would be new one for END.
427 // Vetoing BEGIN event means that label editing won't happen at all,
428 // vetoing END means that the new value is discarded and the old one kept
429 //#define EVT_TREEVIEW_BEGIN_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_LABEL_EDIT, id, fn)
430 //#define EVT_TREEVIEW_END_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(END_LABEL_EDIT, id, fn)
432 // provide/update information about GetItem() item
433 //#define EVT_TREEVIEW_GET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(GET_INFO, id, fn)
434 //#define EVT_TREEVIEW_SET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(SET_INFO, id, fn)
436 // GetItem() is the item being expanded/collapsed, the "ING" versions can use
437 //#define EVT_TREEVIEW_ITEM_EXPANDED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDED, id, fn)
438 //#define EVT_TREEVIEW_ITEM_EXPANDING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDING, id, fn)
439 //#define EVT_TREEVIEW_ITEM_COLLAPSED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSED, id, fn)
440 //#define EVT_TREEVIEW_ITEM_COLLAPSING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSING, id, fn)
442 // GetOldItem() is the item which had the selection previously, GetItem() is
443 // the item which acquires selection
444 #define EVT_TREEVIEWLIST_SEL_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGED, id, fn)
445 #define EVT_TREEVIEWLIST_SEL_CHANGING(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGING, id, fn)
447 // GetKeyCode() returns the key code
448 // NB: this is the only message for which GetItem() is invalid (you may get the
449 // item from GetSelection())
450 #define EVT_TREEVIEWLIST_KEY_DOWN(id, fn) wx__DECLARE_TREEVIEWLISTEVT(KEY_DOWN, id, fn)
451 #define EVT_TREEVIEWLIST_CONTEXTUAL_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(CONTEXTUAL_MENU, id, fn)
452 #define EVT_TREEVIEWLIST_ITEM_STYLE_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_STYLE_CHANGED, id, fn)
454 // GetItem() returns the item being deleted, the associated data (if any) will
455 // be deleted just after the return of this event handler (if any)
456 //#define EVT_TREEVIEWLIST_DELETE_ITEM(id, fn) wx__DECLARE_TREEVIEWLISTEVT(DELETE_ITEM, id, fn)
458 // GetItem() returns the item that was activated (double click, enter, space)
459 //#define EVT_TREEVIEWLIST_ITEM_ACTIVATED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_ACTIVATED, id, fn)
461 // GetItem() returns the item for which the context menu shall be shown
462 //#define EVT_TREEVIEWLIST_ITEM_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MENU, id, fn)
464 // GetItem() returns the item that was clicked on
465 //#define EVT_TREEVIEWLIST_ITEM_RIGHT_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_RIGHT_CLICK, id, fn)
466 //#define EVT_TREEVIEWLIST_ITEM_MIDDLE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MIDDLE_CLICK, id, fn)
468 // GetItem() returns the item whose state image was clicked on
469 //#define EVT_TREEVIEWLIST_STATE_IMAGE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(STATE_IMAGE_CLICK, id, fn)
471 // GetItem() is the item for which the tooltip is being requested
472 //#define EVT_TREEVIEWLIST_ITEM_GETTOOLTIP(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_GETTOOLTIP, id, fn)
479 //====================================================================
480 class WxGimmickFrame : public wxFrame
483 WxGimmickFrame( wxWindow *parent, wxString title, wxSize size);
486 WxGimmick* GetWxGimmick() { return mWxGimmick; }
488 void OnSelChanged(WxGimmickEvent& event);
491 DECLARE_EVENT_TABLE();
494 WxGimmick* mWxGimmick;
496 //====================================================================
500 } // namespace creaImageIO
503 #endif // #ifndef __creaImageIOWxGimmick_h_INCLUDED__