G4P Cancel Selection in Textfield?

Hi Peter et al, just wondering if there’s a way to use the .cancelSelection() method for G4P texfields?

Here’s the code:

void unselectAllFields() {
  tfCC0.cancelSelection();
  tfCC1.cancelSelection();
  tfCC2.cancelSelection();
  tfCC3.cancelSelection();
  tfCC0Name.cancelSelection();
  tfCC1Name.cancelSelection();
  tfCC2Name.cancelSelection();
  tfCC3Name.cancelSelection();
  tfM0.cancelSelection();
  tfM1.cancelSelection();
  tfM2.cancelSelection();
  tfM3.cancelSelection();
  tfRH0.cancelSelection();
  tfRH1.cancelSelection();
  tfRH2.cancelSelection();
  tfRH3.cancelSelection();
  
}

But the error says : “The method cancelSelection() from the type GTextField is not visible”

Also, is there a better way to iterate through all the controls rather than itemizing them one at at time?

Thanks for any insights!

Mike

1 Like

I will make the cancelSelection method public for the next release. Just a warning though calling this method from inside a Processing key event handler e.r. keyTyped will crash the sketch. Use another control e.g. a button to cancel selections in text fields and areas.

The easiest way is simply add the controls to a list then iterate over them like this-

import g4p_controls.*;

ArrayList<GTextField> listA = new ArrayList<GTextField>();

public void setup() {
  size(400, 240, JAVA2D);
  createGUI();
  addToList(listA, txf1, txf2, txf3);
  setRandomText(listA, 20, 30);
}

public void draw() {
  background(230, 230, 255);
}

void setRandomText(ArrayList<GTextField> list, int minLength, int maxLength) {
  for (GTextField field : list) {
    int len = (int) random(minLength, maxLength);
    int pos = (int) random(0, rawText.length() - len);
    field.setText(rawText.substring(pos, pos+len));
  }
}

void addToList(ArrayList<GTextField> list, GTextField... fields) {
  for (GTextField field : fields) list.add(field);
}

String rawText = "Lorem Ipsum is simply dummy text of the "
  +"printing and typesetting industry. Lorem Ipsum has been "
  +"the industry's standard dummy text ever since the 1500s, "
  +"when an unknown printer took a galley of type and "
  +"scrambled it to make a type specimen book. It has "
  +"survived not only five centuries, but also the leap into "
  +"electronic typesetting, remaining essentially unchanged. "
  +"It was popularised in the 1960s with the release of "
  +"Letraset sheets containing Lorem Ipsum passages, and more "
  +"recently with desktop publishing software like Aldus "
  +"PageMaker including versions of Lorem Ipsum.";

public void randomIntput(GButton source, GEvent event) {
  setRandomText(listA, 20, 30);
}

public void createGUI() {
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  G4P.setInputFont("Arial", G4P.PLAIN, 14);
  surface.setTitle("Sketch Window");
  txf1 = new GTextField(this, 20, 20, 370, 20, G4P.SCROLLBARS_NONE);
  txf1.setOpaque(true);
  txf2 = new GTextField(this, 20, 50, 370, 20, G4P.SCROLLBARS_NONE);
  txf2.setOpaque(true);
  txf3 = new GTextField(this, 20, 80, 370, 20, G4P.SCROLLBARS_NONE);
  txf3.setOpaque(true);
  btnRandom = new GButton(this, 220, 120, 170, 30);
  btnRandom.setText("Randomise Text");
  btnRandom.addEventHandler(this, "randomIntput");
}

GTextField txf1;
GTextField txf2;
GTextField txf3;
GButton btnRandom;
2 Likes

Fantastic Peter! Thank you so much! I knew my code was goofy. The array list will be perfect!

EDIT: I just implemented it, and it’s so much more streamlined! Thank you so much!!!

The reason for asking for the cancelSelection to be available is because I noticed if I have a group of textfields, and I highlight text in one, then click on another, the first one remains selected…so it’s odd for the user in this case. Perhaps there’s another way to handle this?

Any chance you can add a “doubleClickSelectAll” to the library while you’re changing the cancelSelection? That way you can double-click in a textfield to select all the text while you’re editing. I guess I use keyboard shortcuts a lot…

Finally, is there an example out there of how to use the GTabcontrol? I googled forever but couldn’t seem to find it anywhere, and it’d be nice to be able to implement it in things.

I am beyond grateful for your support. Thank you so much for your time and attention.

All my best,

Mike

Here’s a much more streamlined version of what I was doing - previously I had listed each field!!!

int WhichFieldHasFocus() {  
 int i = 0;  
 for (GTextField field : listA) {   
   if (field.hasFocus()) return i;
   i++;
 } 
 return 99;//if no field has the focus    
}

This works just wonderfully to easily determine which field has focus!

By the way - in case you’re curious - this is what all your free tech support is helping me build:

Music Fader App

You can skip to around 1:23 to see it in action so far.

Thank you again!!

Mike

Sorry for another post, but I’m just really grateful!

Old code:

void tabNav() {
  
  switch (fieldNum) {
    case 0:
      tfSceneName.setFocus(true);
      break;
      
    case 1:
      tfCC0.setFocus(true);
      break;
      
    case 2:
      tfCC1.setFocus(true);
      break;
      
    case 3:
      tfCC2.setFocus(true);
      break;
      
    case 4:
      tfCC3.setFocus(true);
      break;
      
    case 5:
      tfCC0Name.setFocus(true);
      break;
      
    case 6:
      tfCC1Name.setFocus(true);
      break;
      
    case 7:
      tfCC2Name.setFocus(true);
      break;
      
    case 8:
      tfCC3Name.setFocus(true);
      break;
      
    case 9:
      tfM0.setFocus(true);
      break;
      
    case 10:
      tfM1.setFocus(true);
      break;
      
    case 11:
      tfM2.setFocus(true);
      break;
      
    case 12:
      tfM3.setFocus(true);
      break;
      
    case 13:
      tfRH0.setFocus(true);
      break;
      
    case 14:
      tfRH1.setFocus(true);
      break;
      
    case 15:
      tfRH2.setFocus(true);
      break;
      
    case 16:
      tfRH3.setFocus(true);
      break;
  }  
    
}//end void

New code:

void tabNav() {
 int i = 0;  
 for (GTextField field : listA) {   
   if (i == fieldNum) field.setFocus(true);
   i++;
 }    
}

fieldNum is a global int I’m using to track things.

Thanks again Peter!!!

The G4P_EditTextControls uses a tab manager. It is very easy to use. In that example we have

GTabManager tt;

  // Create the tab manager and add these controls in tab order
  tt = new GTabManager();
  tt.addControls(txf1, pwd1, txa1, txf2, txa2);

We have 5 controls 2 textfields, 2 textareas and 1 password field. Tab key moves forward and Shift+Tab moves backward - it does not loop.

I will look into the possibility of doing this but it depends on how Processing detects and manages the double-click event.

The selection is kept after the control loses focus so that it can be styled e.g. make italic, bold etc. by clicking another button or whatever… See G4P_TextAreaControl.

Once I have made cancelSelection public there is a simple solution :smile:.

The code snippet below comes from the validation example. In this code the textfield cancels any text selection when it loses focus - see the penultimate statement.

public void updateTextField(GTextField source, VR vr, int colScheme, GEvent event) {
  switch(event) {
  case LOST_FOCUS:
    // If validation has calculated an acceptable value display it
    if (!vr.valid && vr.value != null) {
      // It is safe to call setText(...) here because the text field
      // is not longer in edit mode.
      source.setText(vr.value.toString());
      colScheme = GCScheme.BLUE_SCHEME; // it is now valid
    }
    source.setLocalColorScheme(colScheme);
    source.cancelSelection();  // cancel any text selection
    break;
1 Like

Absolutely excellent! Thank you sooo much!

I feel completely embarrassed to be asking you so many questions and taking up so much of your time.

But I do appreciate your kind and fabulous support. Thank you Peter!!!

Btw, any idea when a new version is out?

Thank you AGAIN!!!

Mike

Oh PS don’t forget about adding the insertText to the text field as well! :partying_face:

Already done and tested - ready to roll :innocent:

Should be in the next 2 weeks but hopefully by next weekend. Last year I rushed out tool tips and now realise they need significant work on placement especially when used with rotated controls.

No need to be embarrassed I could always ignore you LOL

2 Likes

:joy: fair enough!

But you can’t, can you?

It’s because you’ve got the bug. To give your absolute very best to ppl always, and to make your library as kickass as poss.

You rock Peter! Thank you!

Mike

1 Like

G4P V4.3.10 is now available at Sourceforge.

It might be a few days before it is available via Contributions Manager, it depends on how often Processing checks for updates.

3 Likes

:partying_face::raised_hands::heart_eyes:

Great work Peter!

Just playing with the new lib - thank you!!!

Couple quick things - it seems the positioning of tooltips is changed? I have values from the previous library, and now the tooltips are in totally different places than originally…and I can’t seem to position them as expected…is there a new way to position them?

I see you have added the inserText to the textfield! Sweet!

I’ll be working with your lovely shiny new library in coming weeks, so again, many kind thanks for all your hard work Peter!!

All the best,

Mike

There are two methods for setting and positioning a tool tip.

The first method defines the alignment relative to the control and has not changed in this version. This is particularly useful for non-rotated controls.

// Create the text tip
void setTip (String text, GAlign ax, GAlign ay, float gap)
// Change the tip pos
void setTipPos (GAlign ax, GAlign ay, float gap)

The implementation of the second method has changed. It was added to work with rotated controls but I created it as an afterthought and never really considered the implementation details. In this version the first parameter (radius) is the distance between the control centre and the tip centre, the second parameter(angle in radians) is the angle made by the line joining the centres.
There is a new library example G4P_ToolTipExplorer where you can try these out.

// Create the text tip
void setTip (String text, float offset, float angle)
// Change its position relative to the controls centre
void setTipPos (float radius, float ang)

Other methods include

// Use a pre-created tool tip - useful for custom tip classes see library example
void setTip (GToolTip tt, float offset, float angle)
void setTip (GToolTip tt, GAlign ax, GAlign ay, float gap)
// Time in ms that the tip remains visible
void setTipDisplayTime (long msecs)
// If level is true keep the tip horizontal no matter what rotation has been 
// applied to the control
void setTipHorz (boolean level)
// Change the tool tip text
void setTipText (String text)

These methods are documented in the GAbstractControl class.

HTH :grinning:

2 Likes

Fantastic Peter! You don’t do “halfway,” do you? :slight_smile:

I only noticed it because, without changing my code, my tips moved, and then I couldn’t figure how to get them where I wanted using cartesian xy coordinates.

But your new examples and implementation are MUCH BETTER than before! And I am able to position the tips more easily now.

And the Tooltip Explorer example is great!

Thank you again kind sir!!!

Mike from Yorkshire

By the way, I am “showing” and “hiding” tips with a checkbox, and when “hiding,” just setting the gap to a huge number like 1000 outside the app window; when not hiding, setting gap back to normal. It seems to work just fine.

Is this the right way to do that?

Also, sometimes I’ve noticed, erratically, the tips shift to the right about 30 pixels or so, same code. I can’t figure out why. I run the app once, tips are centered as I want; I stop and run it again, they are shifted…

Using this code:

 tfCC0.setTip("0 - 127", GAlign.CENTER, GAlign.NORTH, toolTipGap);

EDIT: On further exploration, it seems to do with whether there is data in the control. If I am using a textfield that is empty, with prompt text visible, the tool tip behaves as expected.

This is a music fader app. Sometimes the external fader is connected, sometimes not.

When I run the app and it connects to the music fader and fills out the data, then it shifts.

But just manually entering data into a control does not change the behavior…I think it might be an interaction between the prompt text and the tool tip?

See pix.

Centered as expected, prompt text only

Not centered as expected, data preloaded

Thanks again!

Mike

I never thought about an option for enabling / disabling tool tips on a control so moving it outside the screen area will work but then you need to remember where the tip was before.

You might try something like this
control.setTipDisplayTime (0);
to hide the text then
control.setTipDisplayTime (2500); // This is the default of 2500ms
I have not tried this I will leave it to you :thinking:

The tool tip position can change or resize if

  • the tool tip text is changed
  • the position or size of the control e.g. GTextField is changed.
  • the tip position is changed with setTipPos(...) - obviously :innocent:

I can’t think of any other circumstance where this can happen.

If you can create a very simple sketch (<50 lines and no external resources) which demonstrates the problem post it here and I will explore it.

Could never see the point in doing that LOL

2 Likes

User error. I was gauging “centeredness” wrong. Of course, with a 0, the tip center looks off because the field is supposed to allow for 3 digits.

My bad!

Great update Peter! I’ll be working with it over the next few weeks. Next I’m going to tackle the insertText feature in the updated textfield.

I’ll raise any questions as a separate thread so it’s easy for people to find answers when searching.

Below is a simple implementation of “showing and hiding” a tooltip using a checkbox.

Thanks again Peter!

Main sketch:

// Need G4P library
import g4p_controls.*;
// You can remove the PeasyCam import if you are not using
// the GViewPeasyCam control or the PeasyCam library.
import peasy.*;

public void setup(){
  size(480, 320, JAVA2D);
  createGUI();
  customGUI();
  
  //tf1.setText("Added in Setup");
  cbShowTips.setSelected(true);
  
}

public void draw(){
  background(230);
  
}

// Use this method to add additional statements
// to customise the GUI controls
public void customGUI(){
  
  tf1.setTip("Test", GAlign.CENTER, GAlign.NORTH, 5);

}

void showHideToolTip() {

  if (cbShowTips.isSelected()) tf1.setTip("Test", GAlign.CENTER, GAlign.NORTH, 5);
  else tf1.setTip("Test", GAlign.CENTER, GAlign.NORTH, 1000);
  
}

gui tab:

/* =========================================================
 * ====                   WARNING                        ===
 * =========================================================
 * The code in this tab has been generated from the GUI form
 * designer and care should be taken when editing this file.
 * Only add/edit code inside the event handlers i.e. only
 * use lines between the matching comment tags. e.g.

 void myBtnEvents(GButton button) { //_CODE_:button1:12356:
     // It is safe to enter your event code here  
 } //_CODE_:button1:12356:
 
 * Do not rename this tab!
 * =========================================================
 */

public void tf1_change1(GTextField source, GEvent event) { //_CODE_:tf1:879879:
  println("textfield1 - GTextField >> GEvent." + event + " @ " + millis());
} //_CODE_:tf1:879879:

public void cbShowTips_clicked1(GCheckbox source, GEvent event) { //_CODE_:cbShowTips:972090:
  println("cbShowTips - GCheckbox >> GEvent." + event + " @ " + millis());
  showHideToolTip();
} //_CODE_:cbShowTips:972090:



// Create all the GUI controls. 
// autogenerated do not edit
public void createGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  surface.setTitle("Sketch Window");
  tf1 = new GTextField(this, 69, 75, 120, 30, G4P.SCROLLBARS_NONE);
  tf1.setPromptText("Enter Text");
  tf1.setOpaque(true);
  tf1.addEventHandler(this, "tf1_change1");
  cbShowTips = new GCheckbox(this, 200, 81, 120, 18);
  cbShowTips.setIconAlign(GAlign.LEFT, GAlign.MIDDLE);
  cbShowTips.setText("Show Tooltip");
  cbShowTips.setOpaque(false);
  cbShowTips.addEventHandler(this, "cbShowTips_clicked1");
}

// Variable declarations 
// autogenerated do not edit
GTextField tf1; 
GCheckbox cbShowTips; 

It would be easy to add the option to enable/disable tooltips. The only questions whether to make it a global feature (affects all controls) or make it control specific.

2 Likes

Turning them off individually would be great; a global option would also be nice. Both?

How much time do you have lol!

In any case, I have showing and hiding working fully, thanks to your other posts and the update to the library! Moving the tip out to Kalamazoo and back works easily.

Also, not to do with this thread, but to do with your library, I now have a separate “options” window where you can turn on or off the tooltips, and the choice is saved to disk for future recall. So cool! Thanks Peter!

Thank you again for such a great library, and all your hard work to maintain it, update it, and help people like me!!

Mike