Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    GeDialog Inserting BitmapButtons [SOLVED]

    SDK Help
    0
    10
    792
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 12/01/2015 at 15:49, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   14 
      Platform:    Mac  ;  
      Language(s) :     C++  ;

      ---------
      Hello, I've been working with some GeDialog plugins and was trying to come up with a way to load a series of images from a folder and display them as buttons that can be clicked to merge an associated C4D file into the scene.

      I've been using this code, inside of a loop, to load the images as BitmapButtonCustomGui, and then code in Command() for when they're pressed.

        
      BitmapButtonCustomGui* myButton;  
        
      BaseContainer bc;                      
      LONG bordertouse =0;  
      bc.SetLong(BITMAPBUTTON_BORDER, bordertouse);  
      bc.SetBool(BITMAPBUTTON_BUTTON, TRUE);  
      bc.SetLong(BITMAPBUTTON_TOGGLE, TRUE);  
        
      myButton = (BitmapButtonCustomGui* )AddCustomGui(currentlocation,CUSTOMGUI_BITMAPBUTTON,"MY BUTTON", 0L,0,0,bc);   
        
        
        
      AutoAlloc<BaseBitmap> bb;  
      Filename bg;  
      bg = previewfolder+Filename("preview1.tif");  
      if (bb->Init(bg) != IMAGERESULT_OK) return TRUE;  
      myButton->SetImage(bb, FALSE);  
      

      This doesn't seem the best way to do this though.  It scales up pretty poorly with more buttons and doesn't seem overly clean.  Is there a better way to load a series of images into buttons dynamically and faster?

      Thanks for any help,
      Dan

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 13/01/2015 at 08:51, xxxxxxxx wrote:

        Hi Dan,

        can you further elaborate what you mean by "scales poorly" and "doesn't seem overly clean"?
        You could do the loading of the images in a separate thread, but I'm not sure that's worth the m ore complicated implementation. Surely depends on your situation.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 26/01/2015 at 09:27, xxxxxxxx wrote:

          Hello, sorry about the super late response, got pull into two more projects and I haven't had time to return to this until now.

          I'll try to make more sense!  By scaling poorly I mean that a hundred images loads quick enough, but a five hundred take more than five times as long, it doesn't seem very efficient.  By clean I mean that loading hundreds of BitmapButtonCustomGui doesn't feel like the right thing to do.  It's technically working, although only with a smaller number of buttons than I would like.

          I've considered separate threads, seems better to be loading the images as time goes on rather than all at once.  I'm not overly sure how to implement it though.  Is there a better type to use to display a long series of  click-able images?

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 26/01/2015 at 09:52, xxxxxxxx wrote:

            I think threads are only worth the effort if you're planning to update the buttons asynchronously and display a proxy image while the actual image is being loaded. 90% of the time is probably IO time which won't get quicker with seperate threads.

            If you can't optimize the images, for instance because you display them from a user folder, you would want to do it like that anyway. 😉

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 28/01/2015 at 05:02, xxxxxxxx wrote:

              Hi Dan,

              in general I agree with Niklas, that the main time spent will be file I/O. If delayed loading in a thread will improve to the "fluffticity" of your dialog, depends heavily on what you are intending to do (general GUI design? update rate?) and the nature of your images (average size of the images (pixel- and byte-wise)? what data type? layers involved? resizing involved?). And so does the implementation...

              Afterall nearly all icon buttons in C4D's GUI are done with the BitmapButton and in my personal layouts, I tend to have lots of toolbars (all in all some hundred buttons for sure) and I don't experience any performance issues.

              Of course I won't deny, that the BitmapButton adds some overhead, but I doubt, this plays a major role compared to the file I/O.

              And of course you always have the option to implement your own GeUserArea, if you feel, you can improve the performance with your own implementation.

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 28/01/2015 at 05:57, xxxxxxxx wrote:

                One important thing to note with the Cinema 4D icons is that they're all contained in one image file. 🙂
                If it's icons like that, you should make sure to load the only once, maybe even on Cinema 4D startup.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 28/01/2015 at 05:59, xxxxxxxx wrote:

                  Yep, which again points to file I/O as the bottle neck.

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 19/02/2015 at 11:46, xxxxxxxx wrote:

                    Thanks for all of the information, I was going to try getting it work via threading.  This is the way I was thinking of doing it, is there a better way?

                    I'm going to start a thread in Message() and have that thread RegistorIcon(), and then once I have it confirmed that it's been loaded I can insert the BitmapButton and it will be quicker.

                      
                    LONG MainDialog::Message(const BaseContainer &msg,BaseContainer &result)  
                    {  
                      switch (msg.GetId())  
                      {  
                          case BFM_SCROLLGROUP_SCROLLED:  
                              {  
                               LONG x1,x2,y1,y2;  
                                  GetVisibleArea(idScrollGroup, &x1, &y1, &x2, &y2);  
                                   
                                if(atTheBottom<y2)//at the bottom of the scrollgroup, which means load more images.  
                                  {  
                                      th.Start();//starts the thread and passes the folder it should load from with RegisterIcon()  
                                      th.threadRunning = TRUE;              
                                      th.currentpath = PathToImages;  
                               }  
                    }  
                      
                      
                    void MyThread::Main()  
                    {  
                      value = 0;  
                      while(threadRunning == TRUE)   
                      {  
                        
                          for (LONG x =0; x<10; x++)  
                          {  
                              if(RegisterIcon(5000+x, Filename(currentpath)+Filename(LongToString(x)))  
                              {  
                                  GePrint("Registered:" +LongToString(x) );  
                              }  
                              else  
                              {  
                                  GePrint("Didn't work:" + LongToString(x));  
                              }  
                        }  
                        threadRunning = FALSE;        //Terminate the thread  
                      }  
                        
                    }  
                    

                    The thread works with registering icons in Command(), but not when called from Message(), every RegisterIcon() returns false.  I'm not very familiar with threads so I could be doing plenty of stuff wrong. Any ideas?

                    Dan

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 23/02/2015 at 08:08, xxxxxxxx wrote:

                      Hi Dan,

                      I'm not sure, that calling RegisterIcon() (actually any of the Register...() functions) from a threaded context is a good idea.
                      Why use RegisterIcon() at all in this context? Can't you load the images straight into BaseBitmaps?

                      And then I'd do the mechanic like so (just a suggestion) :

                      • on BFM_SCROLLGROUP_SCROLLED trigger your thread (and give it info, which images to load)
                      • Now, your thread(s) loads images in the background. As soon as its done, it sends a special message
                      • on reception of this message you update your BitmapButtons with the loaded images
                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 11/03/2015 at 10:51, xxxxxxxx wrote:

                        Just want to check, if you have made any progress?

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post