]> Creatis software - creaImageIO.git/blob - src/creaImageIOWxGimmick.h
Initial revision
[creaImageIO.git] / src / creaImageIOWxGimmick.h
1 #ifndef __creaImageIOWxGimmick_h_INCLUDED__
2 #define __creaImageIOWxGimmick_h_INCLUDED__
3
4 // dicom database
5 #include <creaImageIOSystem.h>
6 #include <creaImageIODicomDatabase.h>
7
8 // wx
9 #include "wx/wx.h"
10 #include "wx/image.h"
11 #include "wx/imaglist.h"
12 #include <wx/splitter.h>
13 #include "treelistctrl.h"
14
15 // dicom fields view panel
16 #include <creaImageIOWxGimmickFieldsView.h>
17 // settings widget
18 #include <creaImageIOWxGimmickSettings.h>
19
20 // For image preview 
21 // vtk and wxvtk classes
22 #include "wxVTKRenderWindowInteractor.h"
23 #include "vtkImageViewer2.h"
24 // multi-thread image reader
25 #include <creaImageIOMultiThreadImageReader.h>
26
27
28 namespace creaImageIO
29 {
30
31   //====================================================================
32   // Forward decl of event class for WxGimmick
33   class WxGimmickEvent;
34   class WxGimmickTreeItemData;
35   class WxGimmickDicomNodeData;
36   //====================================================================
37
38   //====================================================================
39   class CREAIMAGEIO_EXPORT WxGimmick : public wxPanel,
40                                   public MultiThreadImageReaderUser
41   {
42   public:
43     WxGimmick(wxWindow *parent, const wxWindowID id,
44                             const wxPoint& pos, const wxSize& size,
45                             int number_of_threads = 0);
46
47     virtual ~WxGimmick();
48
49     typedef std::vector<DicomDatabase*> DicomDatabaseListType;
50
51     DicomDatabaseListType& GetDicomDatabaseList() { return mDicomDatabaseList; }
52     const DicomDatabaseListType& GetDicomDatabaseList() const { return mDicomDatabaseList; }
53     
54     wxTreeListCtrl* GetTreeListCtrl() { return mTreeListCtrl; }
55     const wxTreeListCtrl* GetTreeListCtrl() const { return mTreeListCtrl; }
56
57     void SetConfigurationFile(const std::string& filename) 
58     {
59       mConfigurationFile = filename;
60     }
61     void LoadConfiguration();
62     void SaveConfiguration();
63     void SetSaveConfigurationOnClose(bool v) 
64     { mSaveConfigurationOnClose = v; }
65
66
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);
71
72
73     static const int UserMenuFirstId;
74
75     typedef WxGimmickSettings Settings;
76     const Settings& GetSettings() const { return mSettings; }
77     Settings& GetSettings() { return mSettings; }
78
79     typedef WxGimmickEvent EventType;
80
81   protected:
82     void RebuildView();
83     void UpdateDicomDatabaseView(DicomDatabase*);
84     void UpdateDicomNodeView(DicomNode* n, const wxTreeItemId& parent);
85     void DeleteObsoleteChildren(wxTreeItemId& id);
86     wxTreeItemId CreateChildrenColumnsTitles(wxTreeItemId& item,
87                                              DicomNode::Type t);
88     void UpdateColumnsTitles(wxTreeItemId& item, DicomNode::Type t);
89     void UpdateColumns(wxTreeItemId& item, bool only_first = false);
90     void OpenOrNewDatabase(bool open);
91
92     void InsertDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
93     void DeleteDicomDatabase(wxTreeItemId& id, DicomDatabase* r);
94
95     friend class WxGimmickEvent;
96
97   private:
98
99     WxGimmick() { }
100     WxGimmick(const WxGimmick& ) { }
101
102     DicomDatabaseListType mDicomDatabaseList;
103
104     wxTreeListCtrl* mTreeListCtrl;
105     wxTreeItemId mTreeRootId;
106     wxTreeItemId mCollectionsTitlesItemId;
107
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;
115
116     std::string mDatabaseExtension;
117     const std::string& GetDatabaseExtension() { return mDatabaseExtension; }
118     void SetDatabaseExtension(const std::string& ext) 
119     { mDatabaseExtension = ext; }
120     Settings mSettings;
121
122     int  mFirstDicomDatabaseIconIndex;
123     // Id of the item which activated the popup menu 
124     wxTreeItemId mItemOfMenu;
125
126
127     /// Preview related stuff
128
129     wxPanel *mPanelImage;
130
131     WxGimmickFieldsView* mFieldsView;
132
133     wxSplitterWindow            *mSplitter1;
134     wxSplitterWindow            *mSplitter2;
135     
136     void ShowImage(vtkImageData* image);
137     void ShowInformation(DicomNode*);
138    // Previewer
139     vtkImageViewer2* mViewer;
140     // Associated wxvtk interactor
141     crea::wxVTKRenderWindowInteractor  *mInteractor;
142   
143     int mx1,mx2,my1,my2,mz1,mz2;
144     double mspx,mspy,mspz;
145   
146     // Image preview :
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
157     {
158       ImageEventType( wxTreeItemId it,  vtkImageData* im )
159         : item(it), image(im) {}
160       ImageEventType(vtkImageData* im )
161         : image(im) {}
162       wxTreeItemId item;
163       vtkImageData* image;
164     };
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();
172     // 
173     void OnInternalIdle();
174
175     typedef WxGimmickTreeItemData TreeItemData;
176     TreeItemData* GetItemData(const wxTreeItemId& id)
177     { return (TreeItemData *)mTreeListCtrl->GetItemData(id); }
178
179     typedef WxGimmickDicomNodeData NodeData;
180     
181   public:
182  
183     // Event callbacks
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);
191
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);
203
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);
218
219     void CreateImageList(int size = 16);
220     void CreateButtonsImageList(int size = 11);
221
222     // Multi-thread image reader callback
223     void OnMultiThreadImageReaderEvent(const std::string& filename,
224                                        MultiThreadImageReaderUser::EventType t,
225                                        vtkImageData* image);
226     /*
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); }
230     */
231
232     void DoToggleIcon(const wxTreeItemId& item);
233
234
235     int ImageSize(void) const { return m_imageSize; }
236
237     // void SetLastItem(wxTreeItemId id) { m_lastItem = id; }
238
239 protected:
240     //    virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
241
242
243 private:
244
245
246     //    void LogEvent(const wxChar *name, const wxTreeEvent& event);
247
248     int          m_imageSize;               // current size of images
249
250     /*
251     bool         m_reverseSort;             // flag for OnCompareItems
252     wxTreeItemId m_lastItem,                // for OnEnsureVisible()
253                  m_draggedItem;             // item being dragged right now
254     */
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()
261 };
262   //====================================================================
263
264
265
266
267
268
269
270
271  //====================================================================
272 class CREAIMAGEIO_EXPORT WxGimmickEvent : public wxNotifyEvent
273 {
274 public:
275     WxGimmickEvent(wxEventType commandType,
276                                  WxGimmick *tree,
277                                  const wxTreeItemId &item = wxTreeItemId());
278
279     WxGimmickEvent(wxEventType commandType = wxEVT_NULL, int id = 0);
280     WxGimmickEvent(const WxGimmickEvent& event);
281
282     virtual wxEvent *Clone() const { return new WxGimmickEvent(*this); }
283
284     // accessors
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; }
289
290         // for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events, get the previously
291         // selected item
292     wxTreeItemId GetOldItem() const { return m_itemOld; }
293     void SetOldItem(const wxTreeItemId& item) { m_itemOld = item; }
294
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; }
299
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; }
304
305     void  SetDicomNode(DicomNode* n) { mDicomNode = n; }
306     DicomNode* GetDicomNode() { return mDicomNode; }
307
308     wxMenu& GetMenu() { return *m_PopUpMenu; }
309     void SetMenu(wxMenu* m) {  m_PopUpMenu = m; }
310   
311   void SetColor(wxColor& c) { mColor=c; }
312   wxColor& GetColor() { return mColor; }
313
314   void* GetUserData() const { return mUserData; }
315   void SetUserData(void* v) { mUserData = v; }
316
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; }
320
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; }
324
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; }
328
329 private:
330   // not all of the members are used (or initialized) for all events
331   wxKeyEvent    m_evtKey;
332   wxTreeItemId  m_item,
333                   m_itemOld;
334   wxMenu* m_PopUpMenu;
335   DicomNode* mDicomNode;
336   wxColor mColor;
337   void* mUserData;
338   //    wxPoint       m_pointDrag;
339   //    wxString      m_label;
340   //    bool          m_editCancelled;
341
342   friend class /*WXDLLEXPORT*/ WxGimmick;
343   //    friend class WXDLLEXPORT wxGenericTreeListCtrl;
344
345     DECLARE_DYNAMIC_CLASS(WxGimmickEvent)
346 };
347  //====================================================================
348
349 typedef void (wxEvtHandler::*WxGimmickEventFunction)(WxGimmickEvent&);
350
351 // ----------------------------------------------------------------------------
352 // tree control events and macros for handling them
353 // ----------------------------------------------------------------------------
354
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()
380
381 #define WxGimmickEventHandler(func) \
382     (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(WxGimmickEventFunction, &func)
383
384 #define wx__DECLARE_TREEVIEWLISTEVT(evt, id, fn) \
385     wx__DECLARE_EVT1(wxEVT_COMMAND_TREEVIEWLIST_ ## evt, id, WxGimmickEventHandler(fn))
386
387 // GetItem() returns the item being dragged, GetPoint() the mouse coords
388 //
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)
393
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)
397
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.
400 //
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)
405
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)
409
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)
415
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)
420
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)
427
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)
431
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)
434
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)
437
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)
441
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)
444
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)
447
448
449
450
451
452
453   //====================================================================
454   class WxGimmickFrame : public wxFrame
455   {
456   public:
457     WxGimmickFrame( wxWindow *parent, wxString title, wxSize size);
458     ~WxGimmickFrame();
459
460     WxGimmick* GetWxGimmick() { return mWxGimmick; }
461
462     void OnSelChanged(WxGimmickEvent& event);
463
464
465     DECLARE_EVENT_TABLE();
466   private :
467     
468     WxGimmick* mWxGimmick;
469   };
470   //====================================================================
471
472
473   
474 } // namespace creaImageIO
475
476
477 #endif // #ifndef __creaImageIOWxGimmick_h_INCLUDED__