Polling within a textbox



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 27/02/2012 at 13:13, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   12 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hey guys,

    I'm trying to do live polling of the text being typed into a textbox. And it's turning out to be very challenging.
    I've gotten some good code from the archives posted by Matthias about how to call to a custom method from the message method. Which works well...Except that it does not work for polling inside of a textbox.

    Here's the Scenario:
    Message() runs continuously all the time. Which can be both a blessing & a curse.
    If I use some code in there to constantly poll the textbox. I can easily tell when a person has typed a specific word. Or even a period.
    But then comes the rub.
    In order to take things any farther. I need to stop polling that text box so I can do some of my own looping and things on the text inside of the textbox. But I can't do that because I'm inside the Message() method...And that never stops....Hence the curse!

    So I thought ok.
    What if I use Message() to poll the textbox, and then jump out of the Message() function once the user types a specific thing. Like a period:

        String text;  this->GetString (1001, text);   //Get the text in the text box  
      LONG sLength = text.GetLength();  
      LONG pos = NULL;  
      Bool lastPeriod = text.FindLast(".",&pos, -1); //Find the last occurrence of a period  
      
      if(lastPeriod)  
       {  
        myCustomMethod(msg); //Go to my custom method where I can work on it safely now  
        return TRUE;   
       }
    

    Which sorta works.
    I do jump out of the message() method and into my custom method successfully.
    But I still have the same problem as before.
    The Message() method is still continuously calling to my custom method. So my custom method is now constantly executing over and over. I haven't solved the problem. I've just moved it to another place.😢

    So I'm stuck in this catch 22 scenario.
    How do you do textbox polling.  But also be able to shut the polling off when you need to?

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 01:28, xxxxxxxx wrote:

    Is this in a description? And what message are you looking for in Message()? My immediate reaction was, won't MSG_DESCRIPTION_CHECKUPDATE do, because that is sent when the user changes something in the AM. You can then test if it's your textbox that's been changed and if so, what the change is. And you only get that message when something has changed, so you don't need to poll.

    Steve



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 08:46, xxxxxxxx wrote:

    Hi Steve,

    I wasn't using a description. But I can easily do that if that's what it needs. My plugin already has a .res file set up in case I need to go that route for anything.
    The problem with that is I don't fully understand all the complex code that this approach would would require.
    If I go with descriptions. That opens up a flood of questions I have about:
    -GetDEnabling
    -GetDDescription
    -DescriptionCommand
    -Etc...

    Since I'm using a dialog. And not a tag or tool plugin. That makes things 100x more complicated for me. Because something as simple a "LONG type" isn't even an overload option for Message() in a dialog plugin.
    I don't know If I'll be able to figure out all of that description stuff out on my own.
    Descriptions are very complex and confusing to me.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 10:20, xxxxxxxx wrote:

    Have you tried to use Command() instead ?
    Maybe I don't fully understand but when an event occurs within your EditText(), Command() is called with its ID.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 11:35, xxxxxxxx wrote:

    Hi Scott,

    Descriptions certainly look more complex at first, but I find them easier than dialogs now. You can't avoid them if you are going to do a tool plugin, tag, shader, etc.

    All you need to know to use descriptions is how to set the default values in the various fields and how to get out what value the user sets. And that's all done through a BaseContainer.

    After that GetDEnabling() is the one to investigate first since that lets you enable/disable the various description elements as required. The other things are for more complex scenarios.

    If I can find the time I'll do a quick tutorial for my site on the basic setting up and handling of descriptions.

    Steve



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 12:01, xxxxxxxx wrote:

    @Yannick,
    I can't use command because that would require the user to physically click on a button, or some other gizmo, to poll the textbox.
    I'm trying to make this happen live. So when the user types "." in the textbox. A ComboButton or a popup list will pop up. And the user can select one of the options. Which will add it to the right of the "." in the text box.

    @Steve,
    What is making this so much harder is that I'm using a dialog plugin.
    There's lots of examples for tags and objects plugins. But they are a little bit easier because *Node  and * Type are built into them. And you can just use them.
    And although dialogs do have the GetDDescription() where these things are available. I don't know how to execute them from one of the other methods at a specific time.
    In other words. I don't understand how GetDDescription() communicates with Message(), Command(), Init(), ect...

    A tutorial about this stuff would be wonderful.
    Thanks for the help,
    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 15:14, xxxxxxxx wrote:

    What's confusing you is probably what confused me at first - you have functions with the same name doing the same overall thing but in a different way. For instance, Atom::Message is quite different from the Message() in the classes derived from BaseData, which is the base class for tool, tags, etc. Then there's GeDialog::Message, which is not derived from Atom but which appears to receive exactly the same messages.

    On top of that you have GeDialog::Command, which indicates that the user has changed something or clicked a button, a function which in descriptions is handled through Message() (there is no Command() for descriptions).

    I can't help thinking that this is the result of years of code being added on and all piled on top without much attempt to rationalise it - probably because, in fairness, to do that would break so much existing code.

    But I'll see what I can do about a descriptions tutorial.

    Steve



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 16:27, xxxxxxxx wrote:

    Ok. Thanks.
    I can't speak for anyone else. But a tutorial on it would really help me a lot.
    Dialog descriptions. What they can, and can't do(example: hide or alter GUI items) are especially confusing to me. But I'm also not really that clear on the tag and object type descriptions too.

    On top of that. I might be trying to do something that just isn't possible in C4D with this live polling of what's being typed into a textbox thing.
    I've seen people do it in raw C#. But I don't know if it's possible in C4D.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 22:20, xxxxxxxx wrote:

    Here is how I've been able to poll the string in an EditText (using Command(), still don't understand why you don't want to use it) and display a PopupMenu:

    class PollTextDialog : public GeDialog
    {
        virtual Bool CreateLayout(void)
        {
            // first call the parent instance
    	    Bool res = GeDialog::CreateLayout();
      
    	    SetTitle("Poll Text Dialog");
      
            GroupBegin(0, BFH_SCALEFIT, 0, 1, String(), 0);
            AddEditText(1028, BFH_SCALEFIT, 150);
            GroupEnd();
      
            return res;
        }
      
        virtual Bool Command(LONG id, const BaseContainer &msg)
        {
            if (id==1028)
            {
                String str;
                if (GetString(1028, str))
                {
                    BaseContainer msg(BFM_EDITFIELD_GETCURSORPOS);
                    GeData data = SendMessage(1028, msg);
                    LONG pos = data.GetLong();
                    if (pos > 0 && str[pos-1]=='.')
                    {
                        LONG editX, editY, editW, editH;
                        if (GetItemDim(1028, &editX, &editY, &editW, &editH))
                        {
                            if (Local2Screen(&editX, &editY))
                            {
                                BaseContainer entries;
                                entries.SetString(FIRST_POPUP_ID+0, "Item1");
                                entries.SetString(FIRST_POPUP_ID+1, "Item2");
                                entries.SetString(FIRST_POPUP_ID+2, "Item3");
                                
                                LONG res = ShowPopupMenu(NULL, editX+(pos*5), editY+editH, entries);
                                if (res!=NULL)
                                {
                                    str += entries.GetString(res);
                                    SetString(1028, str);
                                    BaseContainer msg(BFM_EDITFIELD_SETCURSORPOS);
                                    msg.SetLong(1, str.GetLength());
                                    GeData data = SendMessage(1028, msg);
                                }
                            }
                        }
                    }
                }
            }
            
            return GeDialog::Command(id,msg);
        }
    };
    

    I'm still trying to get the pixel position of the cursor in the EditText to open the PopupMenu just below it.
    Edit : changed editX to editX+(pos*5)



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 23:23, xxxxxxxx wrote:

    You've got some R13 only stuff in there and I'm not set up to compile for R13 at the moment.
    When I was getting undefined errors I took a look at the R13 Docs. And noticed that there's a ton of new stuff they added that might easily go unnoticed. Including cursor   position(BFM_EDITFIELD_GETCURSORPOS) that isn't in R12.

    I'll have to try and get myself set up with the R13 demo so I can try out your code.
    Looks like they added some neat things that I wasn't even aware of in R13.

    Thanks a ton for the example.🍺

    -ScottA

    *Edit-- I just got things set up for R13 and it works like a charm. Very cool stuff.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/02/2012 at 23:55, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    You've got some R13 only stuff in there and I'm not set up to compile for R13 at the moment.
    When I was getting undefined errors I took a look at the R13 Docs. And noticed that there's a ton of new stuff they added that might easily go unnoticed. Including cursor   position(BFM_EDITFIELD_GETCURSORPOS) that isn't in R12.

    Ah sorry, didn't remembered you're working with R12.

    Originally posted by xxxxxxxx

    *Edit-- I just got things set up for R13 and it works like a charm. Very cool stuff.

    Glad you could try the code. The 'magic' size of a character's is not good practice but SizeChr() doesn't give a useful value in this case. I'm not sure if this hardcoded size works for both Windows and Mac.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 29/02/2012 at 15:50, xxxxxxxx wrote:

    Yannick.
    Do you know if this same thing is possible to do in R12?
    I've been trying the various BFM's that are in R12. But I can't make the popup GUI trigger while the cursor is still inside of the textbox.
    It will trigger the popup once I click someplace else in the dialog. But this is of course not a desired result.
    I think I'm using the BFM's wrong:

      
       if(id==MY_TEXT_FIELD)  
        {  
         String text;                                      //Create a variable to assign to the text that's in the textbox  
         if(GetString(MY_TEXT_FIELD, text))                //Get the text using that new variable   
          {   
           msg.GetLong(BFM_INPUT_DEVICE) == BFM_INPUT_KEYBOARD;//<---Wrong?  
      
           LONG slength = text.GetLength();                    //Get the total size of the string  
      
           LONG editX, editY, editW, editH;                            //Create some variables to position the popup GUI  
           GetItemDim(MY_TEXT_FIELD, &editX, &editY, &editW, &editH);   
           Local2Screen(&editX, &editY);  
           BaseContainer entries;  
           entries.SetString(FIRST_POPUP_ID+0, "Item1");  
           entries.SetString(FIRST_POPUP_ID+1, "Item2");  
           entries.SetString(FIRST_POPUP_ID+2, "Item3");  
      
           if(slength > 10)  //<--This value is the trigger for the popup to execute  
            {  
            LONG popup = ShowPopupMenu(NULL, editX, editY+editH, entries);  
            if(popup!=NULL)  
             {  
              text += entries.GetString(popup);  
              SetString(MY_TEXT_FIELD, text);  
              GeData data = SendMessage(MY_TEXT_FIELD, msg);  //<---either Wrong or not working  
             }  
            }  
           }  
         }
    

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 08/03/2012 at 00:34, xxxxxxxx wrote:

    Hi Scott,
    I'm not quite sure, if I understood your "live polling" question correctly and if your actual request has been solved.
    As you seem to be in a dialog, I think you could have another look at my ColourTable example (I posted a link in "Descriptions Vs. AddItem" thread). There I'm coloring the cursor, while the user is typing, depending on a search result (see ColourTableSubDialog::ColorSearchAndSet(void), which is called from Command()).
    And then you were asking, how to stop working on the text field input, as Message() or Command() are called over and over. Couldn't you just store the text input and do your thing, only if the actual data changed. This also opens the possibility to filter strange user inputs or to do nothing, if the user changed the field but ended up with the same input...
    Hope this was of any help,
    Andreas



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 08/03/2012 at 08:37, xxxxxxxx wrote:

    Hi Andreas,
    I'll take another look at your files. And see if there's something in there that might help.

    Thanks for the help,
    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 08/03/2012 at 11:35, xxxxxxxx wrote:

    Scott, sorry, I forgot to mention the file: colourtable.cpp


Log in to reply