ITabDialog.h

Go to the documentation of this file.
00001 /**********************************************************************
00002  *<
00003    FILE: ITabDialog.h
00004 
00005    DESCRIPTION: Interface for tabbed dialogs
00006 
00007    CREATED BY: Cleve Ard
00008 
00009    HISTORY: Created 01 October 2002
00010       24 March 2003 - Updated for R6. This update allows the
00011       current renderer to control which tabs are present in the
00012       render dialog.
00013 
00014  *>   Copyright (c) 2002, All Rights Reserved.
00015  **********************************************************************/
00016 
00017 #pragma once
00018 
00019 #include "maxheap.h"
00020 #include "3dsmaxport.h"
00021 #include "ifnpub.h"
00022 #include "GetCOREInterface.h"
00023 #include "Animatable.h"
00024 #include <CommCtrl.h>
00025 
00026 // forward declarations
00027 class ITabbedDialog;
00028 class ITabPage;
00029 class ITabRegister;
00030 class ITabDialogProc;
00031 class ITabPageProc;
00032 class ITabDialogFilter;
00033 class IRollupWindow;
00034 class ITabDialogPluginTab;
00035 class ReferenceMaker;
00036 
00037 //**********************************************************************
00038 //
00039 // ITabDialogManager
00045 //**********************************************************************/
00046 class ITabDialogManager : public FPStaticInterface
00047 {
00048 public:
00049 
00061    virtual ITabbedDialog* CreateTabbedDialog(
00062       HWND        parent,
00063       HINSTANCE      instance,
00064       const MCHAR*        dlg,
00065       ITabDialogProc*   mainProc,
00066       bool        multiline,
00067       DWORD       helpID=0,
00068       int            tabID = -1,
00069       const Class_ID&   dialogID = Class_ID(0,0)
00070    ) = 0;
00071    
00077    virtual bool RegisterTab(const Class_ID& dialogID, ITabDialogPluginTab* tab) = 0;
00078 
00084    virtual void UnRegisterTab(const Class_ID& dialogID, ITabDialogPluginTab* tab) = 0;
00085 
00087 
00090    virtual void SetTabFilter(const Class_ID& dialogID, ITabDialogFilter* filter) = 0;
00091 
00093 
00096    virtual ITabDialogFilter* GetTabFilter(const Class_ID& dialogID) = 0;
00097 
00099 
00105    virtual ITabbedDialog* GetTabbedDialog(const Class_ID& dialogID) = 0;
00106 
00108 
00111    static int AcceptTab(
00112       ITabDialogFilter*    filter,
00113       ITabDialogPluginTab* tab
00114    );
00115 };
00116 
00122 
00123 #define TAB_DIALOG_PREFERENCES_ID   Class_ID(0x16d416fb, 0x1cdd4da5) //!< \brief Preferences dialog
00124 #define TAB_DIALOG_PROPERTIES_ID Class_ID(0x777f709b, 0x44404554) //!< \brief Object Properties dialog
00125 #define TAB_DIALOG_PATH_ID       Class_ID(0x2c863840, 0x67b1202f) //!< \brief Configure Path dialog
00126 #define TAB_DIALOG_RENDER_ID     Class_ID(0x648636a0, 0xe52086b) //!< \brief Render dialogs
00127 #define TAB_DIALOG_VIDEO_POST_ID Class_ID(0x41be0fad, 0x160c099c) //!< \brief Render dialogs
00128 
00129 #if defined(ENVIRONMENT_DIALOG_IN_RENDER_DIALOG)
00130 #define TAB_DIALOG_ENVIRONMENT_ID   TAB_DIALOG_RENDER_ID
00131 #else // defined(environment_dialog_in_render_dialog)
00132 #define TAB_DIALOG_ENVIRONMENT_ID   Class_ID(0x447f2d77, 0x781268a7)
00133 #endif   // defined(environment_dialog_in_render_dialog)
00134 
00135 #define TAB_DIALOG_CUSTOMIZE_ID     Class_ID(0x27A3F8FB, 0x8D294d77)
00136 
00137 
00138 // These are the results of accepting a tab for a dialog
00139 enum {
00140    TAB_DIALOG_REMOVE_TAB = 1,
00141    TAB_DIALOG_ADD_TAB = 2
00142 };
00143 
00144 #define TAB_DIALOG_MANAGER_INTERFACE_ID Interface_ID(0x46465ead, 0x6e3cbb)
00145 
00146 // This inline will return the ITabDialogManager.
00147 inline ITabDialogManager* GetTabDialogManager()
00148 {
00149    return static_cast<ITabDialogManager*>(
00150       GetCOREInterface(TAB_DIALOG_MANAGER_INTERFACE_ID));
00151 }
00152 
00153 #pragma warning(push)
00154 #pragma warning(disable:4100)
00155 
00156 /***********************************************************************
00157  *
00158  * ITabDialogPluginTab
00163 // **********************************************************************/
00164 class ITabDialogPluginTab : public BaseInterface {
00165 public:
00167 
00171    virtual void AddTabToDialog(ITabbedDialog* dialog) = 0;
00172 
00178    virtual int AcceptDialog(
00179       ITabDialogFilter* filter
00180    ) { return TAB_DIALOG_ADD_TAB; }
00181 
00185    virtual ReferenceMaker* GetReferenceMaker() { return NULL; }
00186 
00188    virtual Animatable* GetAnimatable() { return (Animatable*)GetReferenceMaker(); }
00189 
00191    virtual Class_ID GetClassID() {
00192       Animatable* a = GetAnimatable();
00193       return a ? a->ClassID() : Class_ID(0, 0);
00194    }
00195    virtual SClass_ID GetSuperClassID() {
00196       Animatable* a = GetAnimatable();
00197       return a ? a->SuperClassID() : 0;
00198    }
00199 
00201    virtual BaseInterface* GetInterface(const Interface_ID& id) { return NULL; }
00202 };
00203 
00204 //***********************************************************************
00205 //
00206 // TabDialogFilter
00211 //**********************************************************************/
00212 class ITabDialogFilter : public BaseInterface {
00213 public:
00214 
00219    virtual int AcceptTab(
00220       ITabDialogPluginTab* tab
00221    ) { return TAB_DIALOG_ADD_TAB; }
00222 
00225    virtual int LaunchDialog(const Class_ID& page = Class_ID(0,0)) { return IDOK; }
00226 
00230    virtual ReferenceMaker* GetReferenceMaker() { return NULL; }
00231 
00233    virtual Animatable* GetAnimatable() { return (Animatable*)GetReferenceMaker(); }
00234 
00236    virtual Class_ID GetClassID() {
00237       Animatable* a = GetAnimatable();
00238       return a ? a->ClassID() : Class_ID(0, 0);
00239    }
00240    virtual SClass_ID GetSuperClassID() {
00241       Animatable* a = GetAnimatable();
00242       return a ? a->SuperClassID() : 0;
00243    }
00244 
00246    virtual BaseInterface* GetInterface(const Interface_ID& id) { return NULL; }
00247 };
00248 
00249 // ***********************************************************************
00250 // 
00256 // **********************************************************************/
00257 
00259 enum TabDialogMessages {
00260    TABDLG_SWITCH_FROM   = WM_USER + 1, 
00261    TABDLG_SWITCH_TO  = WM_USER + 2, 
00262    TABDLG_COMMIT     = WM_USER + 3, 
00263    TABDLG_PRECOMMIT  = WM_USER + 4, 
00264 
00265 
00266    TABDLG_CANCEL     = WM_USER + 5, 
00267    TABDLG_CLOSE      = WM_USER + 6, 
00268    TABDLG_INVALIDATE = WM_USER + 7, 
00269    TABDLGNOTIFY_GETINITINFO   = WM_USER + 8, 
00270    TABDLG_RESIZE_DIALOG= WM_USER + 9   
00271 };
00273 
00282 struct TABDLG_NMHDR: public MaxHeapOperators 
00283 {
00284    NMHDR hdr;//the common denominator
00285             //we use the 
00286    LPARAM dwInitParam; 
00287 };
00288 
00289 #define TABBED_DIALOG_INTERFACE_ID Interface_ID(0x4128621b, 0x744d5789)
00290 
00291 // ***********************************************************************
00292 //
00293 // ITabbedDialog
00300 // **********************************************************************/
00301 class ITabbedDialog: public MaxHeapOperators {
00302 public:
00303    enum {
00304       kSystemPage = 20,
00305       kNormalPage = 50,
00306       kMaxPage = 100
00307    };
00308    
00309    static ITabbedDialog* GetPointer(HWND dialog) {
00310       return DLGetWindowLongPtr<ITabbedDialog*>(dialog);
00311    }
00312 
00314    virtual void DeleteThis() = 0;
00315 
00317    virtual Class_ID GetDialogID() const = 0;
00318 
00332     virtual ITabPage* AddPage(
00333       const MCHAR*              text,
00334       HINSTANCE            instance,
00335       const MCHAR*              tmplt,
00336       ITabPageProc*        proc,
00337       const Class_ID&         pageID,
00338       ITabDialogPluginTab* plugin = NULL,
00339       DWORD             helpID = 0,
00340       int                  order = kNormalPage,
00341       int                  image = -1
00342    ) = 0;
00343    
00358    virtual ITabPage* AddRollout(
00359       const MCHAR*              text,
00360       ITabPageProc*        proc,
00361       const Class_ID&         pageID,
00362       ITabDialogPluginTab* plugin = NULL,
00363       int                  controlID = -1,
00364       int                  width = 0,
00365       int                  bottomMargin = 0,
00366       DWORD             helpID = 0,
00367       int                  order = kNormalPage,
00368       int                  image = -1
00369    ) = 0;
00370 
00372    virtual void SyncRegisteredTabs() = 0;
00373 
00376    virtual ITabDialogFilter* GetTabFilter() const = 0;
00377 
00380    virtual ITabDialogProc* GetProc() const = 0;
00383    virtual ITabDialogProc* SetProc(ITabDialogProc* newProc) = 0;
00384    
00386    virtual INT_PTR DoModal(const Class_ID& page) = 0;
00387    
00389    virtual bool DoFloater(const Class_ID& page) = 0;
00390 
00392    virtual void Switch(const Class_ID& page) = 0;
00393 
00395    virtual void Invalidate() = 0;
00396       
00398    virtual void SetImageList(HIMAGELIST list) = 0;
00399       
00401    virtual int CurrentPage() const = 0;
00402 
00404 
00412    virtual void SetMargins(int left, int top, int right, int bottom) = 0;
00413 
00415 
00419    virtual void SetTabbedRect(const RECT& rect) = 0;
00420       
00422    virtual int GetNbPages() const = 0;
00424    virtual ITabPage* GetPage(int index) const = 0;
00426    virtual ITabPage* GetPage(const Class_ID& id) const = 0;
00427 
00429    virtual HWND GetHWND() const = 0;
00430 
00432    virtual bool OkToCommit() = 0;
00434    virtual bool CommitPages() = 0;
00435 
00437 
00439    virtual void CloseDialog() = 0;
00441 
00443    virtual void ClosePages() = 0;
00444 
00446    virtual void CancelDialog() = 0;
00448    virtual void CancelPages() =0;
00449 
00451    virtual HWND GetTabHWND() const = 0;
00452 
00453 protected:
00454    // Don't allow it to be deleted except through DeleteThis
00455    virtual ~ITabbedDialog() {}
00456 };
00457 
00458 // ***********************************************************************
00459 // *
00460 // * TabDialogPointer
00464 // **********************************************************************/
00465 class TabDialogPointer: public MaxHeapOperators {
00466 public:
00467    TabDialogPointer() : mpDlg(NULL) { }
00468    explicit TabDialogPointer(ITabbedDialog* dlg) : mpDlg(dlg) { }
00469    explicit TabDialogPointer(TabDialogPointer& src) : mpDlg(src.mpDlg) { src.mpDlg = NULL; }
00470    TabDialogPointer(
00471       HWND        parent,
00472       HINSTANCE      instance,
00473       const MCHAR*        dlg,
00474       ITabDialogProc*   mainProc,
00475       bool        multiline,
00476       DWORD       helpID = 0,
00477       int            tabID = -1,
00478       const Class_ID&   dialogID = Class_ID(0,0)
00479    ) : mpDlg(NULL)
00480    {
00481       ITabDialogManager* i = GetTabDialogManager();
00482       if (i != NULL) {
00483          mpDlg = i->CreateTabbedDialog(parent, instance, dlg, mainProc,
00484             multiline, helpID, tabID, dialogID);
00485       }
00486    }
00487 
00488    ~TabDialogPointer() { FreeDlg(); mpDlg = NULL; }
00489 
00490    TabDialogPointer& operator=(ITabbedDialog* dlg) { FreeDlg(); mpDlg = dlg; return *this; }
00491    TabDialogPointer& operator=(TabDialogPointer& src) { FreeDlg(); mpDlg = src.mpDlg; src.mpDlg = NULL; return *this; }
00492 
00493    operator ITabbedDialog*() { return mpDlg; }
00494    ITabbedDialog& operator*() { return *mpDlg; }
00495    ITabbedDialog* get() { return mpDlg; }
00496    ITabbedDialog* release() { ITabbedDialog* dlg = mpDlg; mpDlg = NULL; return dlg; }
00497    ITabbedDialog* operator->() { return mpDlg; }
00498    ITabbedDialog** operator&() { return &mpDlg; }
00499 
00500    bool Create(
00501       HWND        parent,
00502       HINSTANCE      instance,
00503       const MCHAR*        dlg,
00504       ITabDialogProc*   mainProc,
00505       bool        multiline,
00506       int            tabID = -1,
00507       DWORD       helpID = 0,
00508       const Class_ID&   dialogID = Class_ID(0,0)
00509    )
00510    {
00511       ITabDialogManager* i = GetTabDialogManager();
00512       if (i != NULL) {
00513          ITabbedDialog* retVal = i->CreateTabbedDialog(parent, instance, dlg, mainProc,
00514             multiline, helpID, tabID, dialogID);
00515          if (retVal != NULL) {
00516             FreeDlg();
00517             mpDlg = retVal;
00518             return true;
00519          }
00520       }
00521       return false;
00522    }
00523 
00524 private:
00525    void FreeDlg() { if (mpDlg != NULL) mpDlg->DeleteThis(); }
00526 
00527    ITabbedDialog*    mpDlg;
00528 };
00529 
00530 // ***********************************************************************
00531 // *
00532 // * ITabPage
00537 // **********************************************************************/
00538 class ITabPage : public BaseInterface {
00539 public:
00541    virtual HWND GetHWND() const = 0;
00542 
00544    virtual Class_ID GetPageID() const = 0;
00545    
00547    virtual int GetHelpID() const = 0;
00548    
00550    virtual ITabbedDialog* GetTabDialog() const = 0;
00551    
00554    virtual ITabPageProc* GetProc() const = 0;
00555    
00559    virtual ITabPageProc* SetProc(ITabPageProc* newProc) = 0;
00560    
00562    virtual ITabDialogPluginTab* GetPlugin() const = 0;
00563    
00565    virtual int GetIndex() const = 0;
00566 
00568    virtual void Invalidate() = 0;
00569 
00571 
00575    virtual IRollupWindow* GetRollout() = 0;
00576 };
00577 
00578 
00579 // ***********************************************************************
00580 // *
00581 // * ITabDialogProc
00582 // *
00589 // **********************************************************************/
00590 class ITabDialogProc : public BaseInterface {
00591 public:
00592    // Construct
00593    ITabDialogProc() : mpDlg(NULL) {}
00594    
00597    void SetTabDialog(ITabbedDialog* dlg) { mpDlg = dlg; }
00600    ITabbedDialog* GetTabDialog() const { return mpDlg; }
00601 
00603 
00606    virtual void DeleteThis() {}
00607 
00609    INT_PTR InitDialog(HWND focus) {
00610       return dialogProc(WM_INITDIALOG, reinterpret_cast<WPARAM>(focus), 0);
00611    }
00612    
00614    void Invalidate() {
00615       dialogProc(TABDLG_INVALIDATE, 0, 0);
00616    }
00617       
00619    bool OkToCommit() {
00620       bool commit = true;
00621       dialogProc(TABDLG_PRECOMMIT, 0, reinterpret_cast<LPARAM>(&commit));
00622       return commit;
00623    }
00624 
00626    void Commit() {
00627       dialogProc(TABDLG_COMMIT, 0, 0);
00628    }
00629 
00631 
00633    void Close() {
00634       dialogProc(TABDLG_CLOSE, 0, 0);
00635    }
00636 
00638    void Cancel() {
00639       dialogProc(TABDLG_CANCEL, 0, 0);
00640    }
00641 
00643 
00650    bool ResizeDialog(SIZE* delta) {
00651       return dialogProc(TABDLG_RESIZE_DIALOG, 0,
00652          reinterpret_cast<LPARAM>(delta)) != 0;
00653 
00654    };
00655 
00657 
00660    virtual INT_PTR dialogProc(
00661       UINT  msg,
00662       WPARAM   wParam,
00663       LPARAM   lParam
00664    ) { return FALSE; }
00665 
00667    virtual BaseInterface* GetInterface(const Interface_ID& id) { return NULL; }
00668    
00669 private:
00670    ITabbedDialog*    mpDlg;
00671 };
00672 
00673 
00674 // ***********************************************************************
00675 // *
00676 // * ITabPageProc
00681 // **********************************************************************/
00682 class ITabPageProc: public MaxHeapOperators {
00683 public:
00684    // Construct
00685    ITabPageProc() : mpPage(NULL) {}
00686      virtual ~ITabPageProc() {;}
00687    
00690    void SetTabPage(ITabPage* page) { mpPage = page; }
00693    ITabPage* GetTabPage() const { return mpPage; }
00694 
00696 
00699    virtual void DeleteThis() {}
00700 
00702    INT_PTR InitPage(HWND focus, LPARAM lparam) {
00703       return dialogProc(WM_INITDIALOG, reinterpret_cast<WPARAM>(focus), lparam);
00704    }
00705    
00707    void Invalidate() {
00708       dialogProc(TABDLG_INVALIDATE, 0, 0);
00709    }
00710       
00712    bool OkToCommit() {
00713       bool commit = true;
00714       dialogProc(TABDLG_PRECOMMIT, 0, reinterpret_cast<LPARAM>(&commit));
00715       return commit;
00716    }
00718    void Commit() {
00719       dialogProc(TABDLG_COMMIT, 0, 0);
00720    }
00721 
00724    void Close() {
00725       dialogProc(TABDLG_CLOSE, 0, 0);
00726    }
00727 
00729    void Cancel() {
00730       dialogProc(TABDLG_CANCEL, 0, 0);
00731    }
00732 
00734    void SwitchFrom() {
00735       dialogProc(TABDLG_SWITCH_FROM, 0, 0);
00736    }
00737    
00739    void SwitchTo() {
00740       dialogProc(TABDLG_SWITCH_TO, 0, 0);
00741    }
00742 
00744 
00747    virtual INT_PTR dialogProc(
00748       UINT  msg,
00749       WPARAM   wParam,
00750       LPARAM   lParam
00751    ) { return FALSE; }
00752    
00753 private:
00754    ITabPage*      mpPage;
00755 };
00756 
00757 
00758 /***********************************************************************
00759  *
00760  * ITabDialogObject
00777 // **********************************************************************/
00778 class ITabDialogObject : public BaseInterface {
00779 public:
00781    virtual void Activate(ITabbedDialog* dialog) { }
00783    virtual void Deactivate(ITabbedDialog* dialog) { }
00784 
00786 
00791    virtual void AddTabToDialog(ITabbedDialog* dialog, ITabDialogPluginTab* tab) { }
00792 
00797    virtual int AcceptTab(
00798       ITabDialogPluginTab* tab
00799    ) { return TAB_DIALOG_ADD_TAB; }
00800 };
00801 
00802 #pragma warning(pop)
00803 
00804 #define TAB_DIALOG_OBJECT_INTERFACE_ID Interface_ID(0x313c6db9, 0x42890bb3)
00805 
00806 inline ITabDialogObject* GetTabDialogObject(InterfaceServer* obj)
00807 {
00808    return static_cast<ITabDialogObject*>(obj->GetInterface(
00809       TAB_DIALOG_OBJECT_INTERFACE_ID));
00810 }
00811 
00812 
00813 inline int ITabDialogManager::AcceptTab(
00814    ITabDialogFilter*    filter,
00815    ITabDialogPluginTab* tab
00816 )
00817 {
00818    int dlgResult = filter == NULL ? TAB_DIALOG_ADD_TAB : filter->AcceptTab(tab);
00819    if (dlgResult & TAB_DIALOG_ADD_TAB) {
00820       dlgResult &= ~TAB_DIALOG_ADD_TAB;
00821       dlgResult |= tab->AcceptDialog(filter);
00822    }
00823    return dlgResult;
00824 }
00825