22 Replies Latest reply: Jan 5, 2012 3:40 AM by Ondrej Vyhlidal RSS

    Create ButtonWidget observer for panel

    Ondrej Vyhlidal

      Hi all,

      Iam trying to create panel with some buttons and some text input (TextEditBoxWidget). I would like to know how to crate one observer fot both items or at least for button. All buttons that Iam using are ButtonWidget. I have created

      IAPButtonActionObserver.cpp which inherits from CObserver, it has AutoAttach, AutoDetach, Upadate, constructor, destructor... than I have here implementation of all methods, and  CREATE_PMINTERFACE(IAPButtonActionObserver, kIAPButtonActionObserverImpl). In my IAPID.h file I have following(except generated code from dollys):

      DECLARE_PMID(kClassIDSpace, kIAPButtonActionObserverBoss, kIAPPrefix + 3)

      DECLARE_PMID(kImplementationIDSpace, kIAPButtonActionObserverImpl, kIAPPrefix + 6)

      // WidgetIDs:

      DECLARE_PMID(kWidgetIDSpace, kIAPPanelWidgetID, kIAPPrefix + 0)

      DECLARE_PMID(kWidgetIDSpace, kImageButtonWidgetID, kIAPPrefix + 2)

      DECLARE_PMID(kWidgetIDSpace, kLinkButtonWidgetID, kIAPPrefix + 3)

      DECLARE_PMID(kWidgetIDSpace, kSlideShowButtonWidgetID, kIAPPrefix + 4)

      DECLARE_PMID(kWidgetIDSpace, kVideoButtonWidgetID, kIAPPrefix + 5)

       

      In resource IAP.fr file :

      Class

                {

                          kIAPButtonActionObserverBoss,

                          kButtonWidgetBoss,

                          {

                                    /**

                                    Handles button press (and release), see IAPButtonActionObserver...

                                    */

                                    IID_IOBSERVER, kIAPButtonActionObserverImpl,

                          }

                },

      and definition of buttons. I know that I should attach use AttachToWidget in observer, but in this observer doesnt inherits from dialog observer, so it hasnt any method like this. So my question is how to connect my observer to button defined on panel??


      Thanks a lot



        • 1. Re: Create ButtonWidget observer for panel
          Manan Joshi Community Member

          What you need to do for this is to first create a boss for your panel, inside this panel you add your observer. Thus when your panel will load all the classes inside that boss gets instantiated i.e. your observer implementation also gets called and inside the observer's autoattach method attach the observer to your buttons and textfield.

           

          Manan Joshi

           

          - Efficient InDesign Solutions -

          MetaDesign Solutions

          http://metadesignsolutions.com/services/indesign-development.php

          • 2. Re: Create ButtonWidget observer for panel
            Ondrej Vyhlidal Community Member

            So if Iam getting everything right DollyXs code generator doesnt generate applicaiton boss??

            When I will create boss for my panel, It should be descendant of AppBoss?

            After that, I should use Class in resource file to create its instatnce, or just AddIn would suffice?

            • 3. Re: Create ButtonWidget observer for panel
              Manan Joshi Community Member

              Your panel boss should derive from an existing pallete boss, that way you will have the basic functionality of the panel. Within this class description you will place the "id, implementation" pair of your observer.

               

              Manan Joshi

               

              - Efficient InDesign Solutions -

              MetaDesign Solutions

              http://metadesignsolutions.com/services/indesign-development.php

              • 4. Re: Create ButtonWidget observer for panel
                Ondrej Vyhlidal Community Member

                Looks interesting, thanks for that, but still I dont know how to write desirable code for that... Do you know where I could find some more about this problem (desription and code)?? I am reading 3 pdf files from adobe, but it is quite wrong organised(from my point of view). pdf files that I have(everything is about cs5.5): getting started, solutions and plugin programming guide 1 and 2. In solutions pdf I found part about using widgets on panels, but it references on  Adobe InDesign CS5 Programming Guide, in the section on “Widget Observer Pattern.” but I found this section only in pdf files for older cs versions...

                Iam new to Indesign plugin development and this looks like to little hell for me...

                • 5. Re: Create ButtonWidget observer for panel
                  Manan Joshi Community Member

                  You could use something like this

                   

                            Class

                            {

                                      kYourPanelPanelBoss,

                                      kPalettePanelWidgetBoss,

                                      {

                                                /** An implementation of ITextControlData, but with interface

                                                identifier of IID_IPANELMENUDATA, serves to name the popout panel menu.

                                                Implementation provided by the API.*/

                                                IID_IPANELMENUDATA,                              kCPanelMenuDataImpl,

                    

                                                IID_IOBSERVER,                                        kYourPanelObserverImpl,

                                      }

                            },

                   

                  Then create a type based on this boss class, and then add your buttons and textbox to this new type.

                   

                  Manan Joshi

                   

                  - Efficient InDesign Solutions -

                  MetaDesign Solutions

                  http://metadesignsolutions.com/services/indesign-development.php

                  • 6. Re: Create ButtonWidget observer for panel
                    Ondrej Vyhlidal Community Member

                    Thank you again,

                    I decided to erease that old project and create new one. So righ now I have clean project, that contains only panel, its boss and other code generated by Dollys. As next step I would like to add some buttons and handle clicking. I should do following steps:

                    1. add this buttons to current PanelWidgetBoss (thats no problem), it is mandatory, to create my boss, when I have this one??

                    2. add ButtonWidgets IDs to resource file (thats no problem)

                    3. create observer and add it to PanelWidgetBoss as a Interface

                    4. implement observer class in some.cpp file

                     

                    Am I right, or not??

                    Are there any tricky parts, that I should be aware of??

                    THX

                    • 7. Re: Create ButtonWidget observer for panel
                      Manan Joshi Community Member

                      That list looks good, i hope by 3 point you have done something as i have postulated in the previous post in this thread.

                       

                      When all is done you can check whether you are getting the call in your observer's autoattach on not when you load your panel. if you get the call then you are on the right path. The next thing that remains then is to just attach the observer to the buttons and the textfield on the panel.

                       

                       

                      Manan Joshi

                       

                      - Efficient InDesign Solutions -

                      MetaDesign Solutions

                      http://metadesignsolutions.com/services/indesign-development.php

                      • 8. Re: Create ButtonWidget observer for panel
                        Ondrej Vyhlidal Community Member

                        Yes, I have done that...

                        Could you look please at this code, that is all that I have added to EP.fr file, please:

                        Class

                                  {

                                            kEPPanelWidgetBoss, //boss of the panel with buttons

                                            kPalettePanelWidgetBoss,

                                            {

                                                      /** The plug-in's implementation of ITextControlData with an exotic IID of IID_IPANELMENUDATA.

                                                      Implementation provided by the API.

                                                      */

                                                      IID_IPANELMENUDATA, kCPanelMenuDataImpl,

                                                      IID_BUTTONACTIONOBSERVER, kButtonActionObserverImpl, //my own interface for button observer

                                            }

                                  },

                        next I have type fot that boss:

                        type EPPanelWidget(kViewRsrcType) : PalettePanelWidget(ClassID = kEPPanelWidgetBoss)

                        {

                                  CPanelMenuData;

                        };

                        next I have:

                        resource EPPanelWidget(kSDKDefPanelResourceID + index_enUS)

                        { ......} where buttons are defined...

                        Is this OK??

                         

                        Next I added following to EPID.h file:

                        DECLARE_PMID(kInterfaceIDSpace, IID_IBUTTONACTIONOBSERVER, kEPPrefix + 0) //add interface

                        DECLARE_PMID(kImplementationIDSpace, kButtonActionObserverImpl, kEPPrefix + 6) //add implementation

                        and

                        // WidgetIDs:

                        DECLARE_PMID(kWidgetIDSpace, kEPPanelWidgetID, kEPPrefix + 0)

                        DECLARE_PMID(kWidgetIDSpace, kImageButtonWidgetID, kEPPrefix + 2)

                         

                         

                         

                         

                        Than I have ButtonActionObserver.cpp file, with following content:

                        #ifndef __IBUTTONACTIONOBSERVER

                        #define __IBUTTONACTIONOBSERVER

                        #include "IPMUnknown.h"

                        #include "IObserver.h"

                        #include "EPID.h"

                        class ButtonActionObserver : public IObserver {

                          enum { kDefaultIID = IID_IBUTTONACTIONOBSERVER };

                        public:

                                  ButtonActionObserver();

                                  ~ButtonActionObserver();

                                  void Update(const ClassID& theChange, ISubject* theSubject, const PMIID &protocol, void* changedBy);

                                  void AutoAttach();

                                  void AutoDetach();

                                  void SetAttachIID(PMIID iid);

                         

                        };

                        CREATE_PMINTERFACE(ButtonActionObserver, kButtonActionObserverImpl)


                        ButtonActionObserver::ButtonActionObserver()

                        {

                        }

                        ButtonActionObserver::~ButtonActionObserver()

                        {

                         

                        }

                         

                        void ButtonActionObserver::AutoAttach()

                        {

                         

                        }

                         

                        void ButtonActionObserver::AutoDetach()

                        {

                        }

                         

                        void ButtonActionObserver::Update(const ClassID& theChange, ISubject* theSubject, const PMIID &protocol, void* changedBy)

                        {

                        }

                        void ButtonActionObserver::SetAttachIID(PMIID iid)

                        {

                        }

                         

                        #endif

                         

                        When I try to compile that it tells me that,

                        CREATE_PMINTERFACE(ButtonActionObserver, kButtonActionObserverImpl) cannot allocate an object of abstract type Button action Observer... I should re-write other methods from IObserver...

                         

                        My question is, if you think that my approach is good and handling button clicks will be working??

                        Thank you




                        • 9. Re: Create ButtonWidget observer for panel
                          Manan Joshi Community Member

                          On the first look the approach looks good, but one thing that i observed wrong in this code is that you must inherit your observer from CObserver not the IObserver interface. As if you use IObserver you won't have the basic functionality that every interface does have in Indesign like the Queryinterface method.

                          In addition to this change your Observer constructor will also change and call the base class constructor with proper argument, refer the SDK it has lot of examples of it.

                           

                          Once you get the code compiled then lets me know if you manage to get your observer called or not.

                           

                          Manan Joshi

                           

                          - Efficient InDesign Solutions -

                          MetaDesign Solutions

                          http://metadesignsolutions.com/services/indesign-development.php

                          • 10. Re: Create ButtonWidget observer for panel
                            Ondrej Vyhlidal Community Member

                            I changed IObserver to CObserver so I have:

                            lass ButtonActionObserver : public CObserver {

                              enum { kDefaultIID = IID_IBUTTONACTIONOBSERVER };

                            public:

                                      ButtonActionObserver(IPMUnknown *boss, PMIID interfaceID = kDefaultIID) : CObserver(this, interfaceID)

                                      {

                                  //what should be there?????

                                      }

                             

                                      ~ButtonActionObserver(){

                             

                                      }

                                      void Update(const ClassID& theChange, ISubject* theSubject, const PMIID &protocol, void* changedBy);

                                      void AutoAttach();

                                      void AutoDetach();

                                      void SetAttachIID(PMIID iid);

                             

                            };

                            CREATE_PMINTERFACE(ButtonActionObserver, kButtonActionObserverImpl)

                             

                            During Initialization Create_PMINTERFACE is called, plugin starts. But when I click on button nothing happens. Could I implement something in AutoAttach method?? Something like:

                            AttachToWidget(kImageButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData); //that is used in Dialog solution


                            • 11. Re: Create ButtonWidget observer for panel
                              Manan Joshi Community Member

                              As you have not added the observer to monitor anything there won't be any call made to the update and nothing will happen, only the observer constructor is called and that is the behaviour that you are observing.

                               

                              What you need to make sure first is that are you getting the call on the AutoAttach or not? Because this method must be called to attach the observer to the subjects. So what you have written must surely be in the AutoAttach method, but things will work only when this method gets called,

                               

                              Manan Joshi

                               

                              - Efficient InDesign Solutions -

                              MetaDesign Solutions

                              http://metadesignsolutions.com/services/indesign-development.php

                              • 12. Re: Create ButtonWidget observer for panel
                                Ondrej Vyhlidal Community Member

                                I found out, that even my constructor isnt called, the only thing that is called is CREATE_PMINTERFACE... (that is the only break point on which app stops...) or maybe my Xcode ignores other breakpoints but it is less likely.

                                 

                                I added to AutoAttach method following and it should be connected to Subject(button) ...

                                void ButtonActionObserver::AutoAttach()

                                {

                                  //CObserver::AutoAttach();

                                  InterfacePtr<ISubject>tmpButton(this, kImageButtonWidgetID);

                                          tmpButton->AttachObserver(this, IID_IBUTTONACTIONOBSERVER);

                                          ASSERT(tmpButton);

                                 

                                  printf("\n Attach");

                                }

                                • 13. Re: Create ButtonWidget observer for panel
                                  Ondrej Vyhlidal Community Member

                                  Hi Manan,

                                  could I have one big request on you? Do you think, that you would find 5 minutes, to look at my code, please? I dont know where I do mistake... button clicking isnt still working and I have no other ideas where could be error...

                                  Thank you in advice

                                  • 14. Re: Create ButtonWidget observer for panel
                                    Manan Joshi Community Member

                                    On noticing your code i figured one problem in it, replace your implemetationID form "IID_BUTTONACTIONOBSERVER" to "IID_IOBSERVER", because you get call on observers only if the implementationID is "IID_IOBSERVER" for other ID's you need to explicitly call your observer's AutoAttach method.

                                     

                                    Try this and let me know if you get any ahead. I hope this should solve your problem.

                                     

                                    Manan Joshi

                                     

                                    - Efficient InDesign Solutions -

                                    MetaDesign Solutions

                                    http://metadesignsolutions.com/services/indesign-development.php

                                    • 15. Re: Create ButtonWidget observer for panel
                                      Ondrej Vyhlidal Community Member

                                      I figured that too, but still nothing is working.. I even tryed to create my own buttonWidget, which inherited from kButtonWidgetBoss, but when I want to create that button I get strange errors

                                      • 16. Re: Create ButtonWidget observer for panel
                                        Ondrej Vyhlidal Community Member

                                        I think that the best way, is to show my code:

                                        EP.fr file (resource file)

                                        http://pastebin.com/nzRXtYwW

                                         

                                        EPID.h header file with IDs:

                                        http://pastebin.com/4QcWfTea

                                         

                                        and my observer file:

                                        http://pastebin.com/qpGRGGT3

                                         

                                        Could you look at this, please??

                                        • 17. Re: Create ButtonWidget observer for panel
                                          Manan Joshi Community Member

                                          Looking at code does not show any error as such, it would take less time if you could share the project with all the files, so that i can debug the project when i have time.

                                           

                                          Manan Joshi

                                           

                                          - Efficient InDesign Solutions -

                                          MetaDesign Solutions

                                          http://metadesignsolutions.com/services/indesign-development.php

                                          • 18. Re: Create ButtonWidget observer for panel
                                            Ondrej Vyhlidal Community Member

                                            thanks, I will upload my project to Dropbox, is it ok for you?? Or do you want to upload files somewhere else??

                                            Thx

                                            • 19. Re: Create ButtonWidget observer for panel
                                              Manan Joshi Community Member

                                              that will do i suppose.

                                              • 20. Re: Create ButtonWidget observer for panel
                                                Community Member

                                                Hi Ondrej

                                                 

                                                 

                                                 

                                                I just created new plugin in DollyXs and everything works fine. In Your code there's few bugs related to attaching observer to Panel and creating button widget based on Panel Wiget

                                                (type ButtonActionWidget(kViewRsrcType) : PalettePanelWidget(ClassID = kButtonActionObserverBoss))

                                                 

                                                I think the easiest way will be if you do exatcly the same. It's only few steps that you need to reproduce.

                                                So. What i have done to create button.

                                                 

                                                1. Created new plugin in DollyXs with panel

                                                 

                                                2. In YourPluginID.h added

                                                     a) DECLARE_PMID(kClassIDSpace, kEPBtnWidgetBoss, kEreaderPluginPrefix + 100 )

                                                         in ClassID: section

                                                     b) DECLARE_PMID(kImplementationIDSpace, kEPBtnObsImpl, kEreaderPluginPrefix + 100 )

                                                         in ImplementationIDs: section

                                                     c) DECLARE_PMID(kWidgetIDSpace, kEPBtnWidgetId, kEreaderPluginPrefix + 100)

                                                          in WidgetIDs: section

                                                 

                                                3. In YourPlugin.fr file.

                                                     a)

                                                          Class { kEPBtnWidgetBoss, kButtonWidgetBoss,

                                                                    {          IID_IOBSERVER,                                                            kEPBtnObsImpl,                                        }}

                                                    

                                                     in class definitions

                                                 

                                                     b)

                                                          type EPBtnWidget(kViewRsrcType)                              : ButtonWidget                                        (ClassID = kEPBtnWidgetBoss)                    {};

                                                 

                                                     in Type definitions

                                                 

                                                     c)

                                                         

                                                                              EPBtnWidget

                                                                        (    

                                                                                        kEPBtnWidgetId, kSysButtonPMRsrcId, kBindNone,

                                                                                        105, 10, 202, 27, kTrue, kTrue, "Your Text",                              ),

                                                 

                                                      in PanelView definition ("Your Text", should be localized)

                                                 

                                                4. In YourPluginFactoryList.h

                                                     REGISTER_PMINTERFACE(CEPBtnObs,                                        kEPBtnObsImpl)

                                                 

                                                5. Created a class for your observer

                                                 

                                                #include <CObserver.h>

                                                #include <ISubject.h>

                                                #include <IBooleanControlData.h>

                                                #include "EreaderPluginID.h"

                                                 

                                                #include "ISubject.h"

                                                class CEPBtnObs : public CObserver {

                                                public:

                                                          CEPBtnObs(IPMUnknown *boss);

                                                 

                                                          ~CEPBtnObs();

                                                          virtual void Update(const ClassID& theChange, ISubject* theSubject, const PMIID &protocol, void* changedBy);

                                                          virtual void AutoAttach();

                                                          virtual void AutoDetach();

                                                };

                                                 

                                                CREATE_PMINTERFACE(CEPBtnObs, kEPBtnObsImpl)

                                                 

                                                CEPBtnObs::CEPBtnObs(IPMUnknown* boss):CObserver(boss)

                                                {

                                                 

                                                }

                                                 

                                                CEPBtnObs::~CEPBtnObs()

                                                {

                                                 

                                                }

                                                 

                                                void CEPBtnObs::AutoAttach()

                                                {

                                                  InterfacePtr<ISubject> theSubject(this, UseDefaultIID());

                                                          if(theSubject != nil)

                                                                    theSubject->AttachObserver(this, IID_IBOOLEANCONTROLDATA);

                                                 

                                                }

                                                 

                                                 

                                                void CEPBtnObs::AutoDetach()

                                                {

                                                  InterfacePtr<ISubject> theSubject(this, UseDefaultIID());

                                                          if(theSubject != nil)

                                                                    theSubject->DetachObserver(this, IID_IBOOLEANCONTROLDATA);

                                                 

                                                }

                                                 

                                                void CEPBtnObs::Update(const ClassID& theChange, ISubject* theSubject, const PMIID &protocol, void* changedBy)

                                                {

                                                          do

                                                          {

                                                                    if(theChange != kTrueStateMessage)

                                                  break;

                                                 

                                                  printf("\n Update");

                                                 

                                                          } while(kFalse);

                                                }

                                                 

                                                 

                                                If follow those steps then you'll be able to create observer in less than 5 minutes.

                                                 

                                                Regards

                                                Bartek

                                                 


                                                • 21. Re: Create ButtonWidget observer for panel
                                                  Manan Joshi Community Member

                                                  Hello Cropas,

                                                   

                                                  That is a good summary of steps given by you, but using this approach we will only be able to create an observer for the button and not the text field i suppose.

                                                  If we place an observer in the panel it can be used for every widget on the panel. So i suppose the previous path that was proposed is altogehter a different route than just creating an observer for button widget.

                                                   

                                                  Manan Joshi

                                                   

                                                  - Efficient InDesign Solutions -

                                                  MetaDesign Solutions

                                                  http://metadesignsolutions.com/services/indesign-development.php

                                                  • 22. Re: Create ButtonWidget observer for panel
                                                    Ondrej Vyhlidal Community Member

                                                    Hi all,

                                                    at first I will try to develop only button observer and when it would be functional I will try to extend project and will see...

                                                    Iam going to try the solution suggested by Cropas,

                                                    Thanks again