#ifndef __creaImageIOWxGimmick_h_INCLUDED__ #define __creaImageIOWxGimmick_h_INCLUDED__ // dicom database #include #include // wx #include "wx/wx.h" #include "wx/image.h" #include "wx/imaglist.h" #include #include "treelistctrl.h" // dicom fields view panel #include // settings widget #include // For image preview // vtk and wxvtk classes #include "wxVTKRenderWindowInteractor.h" #include "vtkImageViewer2.h" // multi-thread image reader #include namespace creaImageIO { //==================================================================== // Forward decl of event class for WxGimmick class WxGimmickEvent; class WxGimmickTreeItemData; class WxGimmickDicomNodeData; //==================================================================== //==================================================================== class CREAIMAGEIO_EXPORT WxGimmick : public wxPanel, public MultiThreadImageReaderUser { public: WxGimmick(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, int number_of_threads = 0); virtual ~WxGimmick(); typedef std::vector DicomDatabaseListType; DicomDatabaseListType& GetDicomDatabaseList() { return mDicomDatabaseList; } const DicomDatabaseListType& GetDicomDatabaseList() const { return mDicomDatabaseList; } wxTreeListCtrl* GetTreeListCtrl() { return mTreeListCtrl; } const wxTreeListCtrl* GetTreeListCtrl() const { return mTreeListCtrl; } void SetConfigurationFile(const std::string& filename) { mConfigurationFile = filename; } void LoadConfiguration(); void SaveConfiguration(); void SetSaveConfigurationOnClose(bool v) { mSaveConfigurationOnClose = v; } void GetSelectedImages(std::vector&); void GetSelectedDicomNodes(std::vector&); void GetSelectedItems(std::vector&); DicomNode* GetDicomNodeOfItem(const wxTreeItemId& i); static const int UserMenuFirstId; typedef WxGimmickSettings Settings; const Settings& GetSettings() const { return mSettings; } Settings& GetSettings() { return mSettings; } typedef WxGimmickEvent EventType; protected: void RebuildView(); void UpdateDicomDatabaseView(DicomDatabase*); void UpdateDicomNodeView(DicomNode* n, const wxTreeItemId& parent); void DeleteObsoleteChildren(wxTreeItemId& id); wxTreeItemId CreateChildrenColumnsTitles(wxTreeItemId& item, DicomNode::Type t); void UpdateColumnsTitles(wxTreeItemId& item, DicomNode::Type t); void UpdateColumns(wxTreeItemId& item, bool only_first = false); void OpenOrNewDatabase(bool open); void InsertDicomDatabase(wxTreeItemId& id, DicomDatabase* r); void DeleteDicomDatabase(wxTreeItemId& id, DicomDatabase* r); friend class WxGimmickEvent; private: WxGimmick() { } WxGimmick(const WxGimmick& ) { } DicomDatabaseListType mDicomDatabaseList; wxTreeListCtrl* mTreeListCtrl; wxTreeItemId mTreeRootId; wxTreeItemId mCollectionsTitlesItemId; std::string mUserSettingsDirectory; void CreateUserSettingsDirectory(); const std::string& GetUserSettingsDirectory(); wxString mCurrentDirectory; std::string mConfigurationFile; std::string mDatabaseListFile; bool mSaveConfigurationOnClose; std::string mDatabaseExtension; const std::string& GetDatabaseExtension() { return mDatabaseExtension; } void SetDatabaseExtension(const std::string& ext) { mDatabaseExtension = ext; } Settings mSettings; int mFirstDicomDatabaseIconIndex; // Id of the item which activated the popup menu wxTreeItemId mItemOfMenu; /// Preview related stuff wxPanel *mPanelImage; WxGimmickFieldsView* mFieldsView; wxSplitterWindow *mSplitter1; wxSplitterWindow *mSplitter2; void ShowImage(vtkImageData* image); void ShowInformation(DicomNode*); // Previewer vtkImageViewer2* mViewer; // Associated wxvtk interactor crea::wxVTKRenderWindowInteractor *mInteractor; int mx1,mx2,my1,my2,mz1,mz2; double mspx,mspy,mspz; // Image preview : // Multi-thread image reader MultiThreadImageReader mReader; // map of images name to node std::map mImageFileNameToNode; // Cur image item to show wxTreeItemId mCurImageItemToShow; // type of image event // If the image pointer is non null then the image is available (loaded) // else it has been unloaded struct ImageEventType { ImageEventType( wxTreeItemId it, vtkImageData* im ) : item(it), image(im) {} ImageEventType(vtkImageData* im ) : image(im) {} wxTreeItemId item; vtkImageData* image; }; // queue of image event typedef std::deque ImageEventQueueType; ImageEventQueueType mImageEventQueue; // Processes the queue of image events // Called in OnInternalIdle(); // (locks the MultiThreadImageReaderEvent mutex) void ProcessImageEvents(); // void OnInternalIdle(); typedef WxGimmickTreeItemData TreeItemData; TreeItemData* GetItemData(const wxTreeItemId& id) { return (TreeItemData *)mTreeListCtrl->GetItemData(id); } typedef WxGimmickDicomNodeData NodeData; public: // Event callbacks // void OnClose(wxCloseEvent& event); void OnBeginDrag(wxTreeEvent& event); void OnBeginRDrag(wxTreeEvent& event); void OnEndDrag(wxTreeEvent& event); void OnBeginLabelEdit(wxTreeEvent& event); void OnEndLabelEdit(wxTreeEvent& event); void OnDeleteItem(wxTreeEvent& event); void OnGetInfo(wxTreeEvent& event); void OnSetInfo(wxTreeEvent& event); void OnItemExpanded(wxTreeEvent& event); void OnItemExpanding(wxTreeEvent& event); void OnItemCollapsed(wxTreeEvent& event); void OnItemCollapsing(wxTreeEvent& event); void OnSelChanged(wxTreeEvent& event); void OnSelChanging(wxTreeEvent& event); void OnTreeKeyDown(wxTreeEvent& event); void OnItemActivated(wxTreeEvent& event); void OnItemRightClick(wxTreeEvent& event); // Pop up menu callbacks void ShowMenu(wxTreeItemId id, const wxPoint& pt); void OnPopUpNewCollection(wxCommandEvent& event); void OnPopUpOpenCollection(wxCommandEvent& event); void OnPopUpCloseCollection(wxCommandEvent& event); void OnPopUpDeleteCollection(wxCommandEvent& event); void OnPopUpAddFile(wxCommandEvent& event); void OnPopUpAddRawFile(wxCommandEvent& event); void OnPopUpAddDirectory(wxCommandEvent& event); void OnPopUpRemove(wxCommandEvent& event); void OnPopUpSettings(wxCommandEvent& event); void OnPopUpAbout(wxCommandEvent& event); void OnPopUpUser(wxCommandEvent& event); void OnPopUpSort(wxCommandEvent& event); void CreateImageList(int size = 16); void CreateButtonsImageList(int size = 11); // Multi-thread image reader callback void OnMultiThreadImageReaderEvent(const std::string& filename, MultiThreadImageReaderUser::EventType t, vtkImageData* image); /* void DoSortChildren(const wxTreeItemId& item, bool reverse = false) { m_reverseSort = reverse; wxTreeListCtrl::SortChildren(item); } void DoEnsureVisible() { if (m_lastItem.IsOk()) EnsureVisible(m_lastItem); } */ void DoToggleIcon(const wxTreeItemId& item); int ImageSize(void) const { return m_imageSize; } // void SetLastItem(wxTreeItemId id) { m_lastItem = id; } protected: // virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2); private: // void LogEvent(const wxChar *name, const wxTreeEvent& event); int m_imageSize; // current size of images /* bool m_reverseSort; // flag for OnCompareItems wxTreeItemId m_lastItem, // for OnEnsureVisible() m_draggedItem; // item being dragged right now */ // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS() // if you want your overloaded OnCompareItems() to be called. // OTOH, if you don't want it you may omit the next line - this will // make default (alphabetical) sorting much faster under wxMSW. // DECLARE_DYNAMIC_CLASS(wxTree) DECLARE_EVENT_TABLE() }; //==================================================================== //==================================================================== class CREAIMAGEIO_EXPORT WxGimmickEvent : public wxNotifyEvent { public: WxGimmickEvent(wxEventType commandType, WxGimmick *tree, const wxTreeItemId &item = wxTreeItemId()); WxGimmickEvent(wxEventType commandType = wxEVT_NULL, int id = 0); WxGimmickEvent(const WxGimmickEvent& event); virtual wxEvent *Clone() const { return new WxGimmickEvent(*this); } // accessors // get the item on which the operation was performed or the newly // selected item for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events wxTreeItemId GetItem() const { return m_item; } void SetItem(const wxTreeItemId& item) { m_item = item; } // for wxEVT_COMMAND_TREE_SEL_CHANGED/ING events, get the previously // selected item wxTreeItemId GetOldItem() const { return m_itemOld; } void SetOldItem(const wxTreeItemId& item) { m_itemOld = item; } // the point where the mouse was when the drag operation started (for // wxEVT_COMMAND_TREE_BEGIN_(R)DRAG events only) or click position // wxPoint GetPoint() const { return m_pointDrag; } // void SetPoint(const wxPoint& pt) { m_pointDrag = pt; } // keyboard data (for wxEVT_COMMAND_TREE_KEY_DOWN only) const wxKeyEvent& GetKeyEvent() const { return m_evtKey; } int GetKeyCode() const { return m_evtKey.GetKeyCode(); } void SetKeyEvent(const wxKeyEvent& evt) { m_evtKey = evt; } void SetDicomNode(DicomNode* n) { mDicomNode = n; } DicomNode* GetDicomNode() { return mDicomNode; } wxMenu& GetMenu() { return *m_PopUpMenu; } void SetMenu(wxMenu* m) { m_PopUpMenu = m; } void SetColor(wxColor& c) { mColor=c; } wxColor& GetColor() { return mColor; } void* GetUserData() const { return mUserData; } void SetUserData(void* v) { mUserData = v; } // label (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only) // const wxString& GetLabel() const { return m_label; } // void SetLabel(const wxString& label) { m_label = label; } // edit cancel flag (for EVT_TREE_{BEGIN|END}_LABEL_EDIT only) // bool IsEditCancelled() const { return m_editCancelled; } // void SetEditCanceled(bool editCancelled) { m_editCancelled = editCancelled; } // Set the tooltip for the item (for EVT\_TREE\_ITEM\_GETTOOLTIP events) // void SetToolTip(const wxString& toolTip) { m_label = toolTip; } // wxString GetToolTip() { return m_label; } private: // not all of the members are used (or initialized) for all events wxKeyEvent m_evtKey; wxTreeItemId m_item, m_itemOld; wxMenu* m_PopUpMenu; DicomNode* mDicomNode; wxColor mColor; void* mUserData; // wxPoint m_pointDrag; // wxString m_label; // bool m_editCancelled; friend class /*WXDLLEXPORT*/ WxGimmick; // friend class WXDLLEXPORT wxGenericTreeListCtrl; DECLARE_DYNAMIC_CLASS(WxGimmickEvent) }; //==================================================================== typedef void (wxEvtHandler::*WxGimmickEventFunction)(WxGimmickEvent&); // ---------------------------------------------------------------------------- // tree control events and macros for handling them // ---------------------------------------------------------------------------- BEGIN_DECLARE_EVENT_TYPES() // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_DRAG, 600) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_RDRAG, 601) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_BEGIN_LABEL_EDIT, 602) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_LABEL_EDIT, 603) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_DELETE_ITEM, 604) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_GET_INFO, 605) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_SET_INFO, 606) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDED, 607) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_EXPANDING, 608) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSED, 609) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_COLLAPSING, 610) DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGED, 666611) DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGING, 666612) DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_KEY_DOWN, 666613) DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_CONTEXTUAL_MENU, 666614) DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_ITEM_STYLE_CHANGED, 666615) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_ACTIVATED, 614) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_RIGHT_CLICK, 615) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MIDDLE_CLICK, 616) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_END_DRAG, 617) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_STATE_IMAGE_CLICK, 618) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_GETTOOLTIP, 619) // DECLARE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEW_ITEM_MENU, 620) END_DECLARE_EVENT_TYPES() #define WxGimmickEventHandler(func) \ (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(WxGimmickEventFunction, &func) #define wx__DECLARE_TREEVIEWLISTEVT(evt, id, fn) \ wx__DECLARE_EVT1(wxEVT_COMMAND_TREEVIEWLIST_ ## evt, id, WxGimmickEventHandler(fn)) // GetItem() returns the item being dragged, GetPoint() the mouse coords // // if you call event.Allow(), the drag operation will start and a // EVT_TREEVIEW_END_DRAG event will be sent when the drag is over. //#define EVT_TREEVIEW_BEGIN_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_DRAG, id, fn) //#define EVT_TREEVIEW_BEGIN_RDRAG(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_RDRAG, id, fn) // GetItem() is the item on which the drop occurred (if any) and GetPoint() the // current mouse coords //#define EVT_TREEVIEW_END_DRAG(id, fn) wx__DECLARE_TREEVIEWEVT(END_DRAG, id, fn) // GetItem() returns the itme whose label is being edited, GetLabel() returns // the current item label for BEGIN and the would be new one for END. // // Vetoing BEGIN event means that label editing won't happen at all, // vetoing END means that the new value is discarded and the old one kept //#define EVT_TREEVIEW_BEGIN_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(BEGIN_LABEL_EDIT, id, fn) //#define EVT_TREEVIEW_END_LABEL_EDIT(id, fn) wx__DECLARE_TREEVIEWEVT(END_LABEL_EDIT, id, fn) // provide/update information about GetItem() item //#define EVT_TREEVIEW_GET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(GET_INFO, id, fn) //#define EVT_TREEVIEW_SET_INFO(id, fn) wx__DECLARE_TREEVIEWEVT(SET_INFO, id, fn) // GetItem() is the item being expanded/collapsed, the "ING" versions can use //#define EVT_TREEVIEW_ITEM_EXPANDED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDED, id, fn) //#define EVT_TREEVIEW_ITEM_EXPANDING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_EXPANDING, id, fn) //#define EVT_TREEVIEW_ITEM_COLLAPSED(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSED, id, fn) //#define EVT_TREEVIEW_ITEM_COLLAPSING(id, fn) wx__DECLARE_TREEVIEWEVT(ITEM_COLLAPSING, id, fn) // GetOldItem() is the item which had the selection previously, GetItem() is // the item which acquires selection #define EVT_TREEVIEWLIST_SEL_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGED, id, fn) #define EVT_TREEVIEWLIST_SEL_CHANGING(id, fn) wx__DECLARE_TREEVIEWLISTEVT(SEL_CHANGING, id, fn) // GetKeyCode() returns the key code // NB: this is the only message for which GetItem() is invalid (you may get the // item from GetSelection()) #define EVT_TREEVIEWLIST_KEY_DOWN(id, fn) wx__DECLARE_TREEVIEWLISTEVT(KEY_DOWN, id, fn) #define EVT_TREEVIEWLIST_CONTEXTUAL_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(CONTEXTUAL_MENU, id, fn) #define EVT_TREEVIEWLIST_ITEM_STYLE_CHANGED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_STYLE_CHANGED, id, fn) // GetItem() returns the item being deleted, the associated data (if any) will // be deleted just after the return of this event handler (if any) //#define EVT_TREEVIEWLIST_DELETE_ITEM(id, fn) wx__DECLARE_TREEVIEWLISTEVT(DELETE_ITEM, id, fn) // GetItem() returns the item that was activated (double click, enter, space) //#define EVT_TREEVIEWLIST_ITEM_ACTIVATED(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_ACTIVATED, id, fn) // GetItem() returns the item for which the context menu shall be shown //#define EVT_TREEVIEWLIST_ITEM_MENU(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MENU, id, fn) // GetItem() returns the item that was clicked on //#define EVT_TREEVIEWLIST_ITEM_RIGHT_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_RIGHT_CLICK, id, fn) //#define EVT_TREEVIEWLIST_ITEM_MIDDLE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_MIDDLE_CLICK, id, fn) // GetItem() returns the item whose state image was clicked on //#define EVT_TREEVIEWLIST_STATE_IMAGE_CLICK(id, fn) wx__DECLARE_TREEVIEWLISTEVT(STATE_IMAGE_CLICK, id, fn) // GetItem() is the item for which the tooltip is being requested //#define EVT_TREEVIEWLIST_ITEM_GETTOOLTIP(id, fn) wx__DECLARE_TREEVIEWLISTEVT(ITEM_GETTOOLTIP, id, fn) //==================================================================== class WxGimmickFrame : public wxFrame { public: WxGimmickFrame( wxWindow *parent, wxString title, wxSize size); ~WxGimmickFrame(); WxGimmick* GetWxGimmick() { return mWxGimmick; } void OnSelChanged(WxGimmickEvent& event); DECLARE_EVENT_TABLE(); private : WxGimmick* mWxGimmick; }; //==================================================================== } // namespace creaImageIO #endif // #ifndef __creaImageIOWxGimmick_h_INCLUDED__