G4P, extend control class?

@quark I would like to add a couple of my own classes to G4P or perhaps request them to be added :wink:
They are both quite simple but I can’t seem to find a way to get the same functionality and look using G4P alone.

  • “Pallet” : A simple “container” for child buttons/fields, the buttons all having the same dimensions and arranged in a line horizontally.
    The Pallet to have a folding action such that when closed it shows just the button at position 1.

In some ways this is similar to a GPanel but without any Tab and could be autosized by taking size of one button and the button count.

  • NumberInputField : TextField that is designed to only accept keyed number input and use of scrollwheel over the field in order to increment/decrement the value.
    I understand we can take a GTextField and filter the input for only numbers and then mouse event & handlers to deal with scrolling the value, but given how common it is to have a input field just used for numbers wouldn’t it make sense to have a class just for this ?

I’ve managed to bodge up versions of both these controls, but really I would like them to be part of G4P so they play nice with other controls and I can just use one GUI library.
Guessing… I would need to rebuild G4P (using Netbeans for example) in order to achieve this or can I get away with just creating my own classes that extend the GAbstractControl ?

1 Like

sort of answering part of my own question here… just extending the GAbstractControl class does not seem to really work as I then need to add workarounds for G4p.registerControl and createEventHandler … I’m presuming anything that will need access to the static constants and methods in core class G4P.java.

Also I should have included in first questions above :
What is the recommened method to retrieve which mouse button was pressed for a GEvent and any modifiers ?

Cheers,
mala

1 Like

It would be simpler to request these to be added to G4P and has the added benefit that they will be available to other users.

Button Palette control

  1. What is special about button b1 that it always visible?
  2. What triggers the expansion / compression of the palette?
  3. Why do all the buttons have to be the same width, it is just as easy to add up the combined widths
    5)?
  4. Are there occasions when you might want the buttons on a vertical palette?
  5. Do the controls have to be buttons what about other controls e.g. sliders, knobs or in fact any visible control?

Number field control

  1. Do you want it to handle all numeric formats i.e. integer, decimal (e.g. -3.14159) and scientific (e.g. 2,7828E-5)?
  2. How does the control handle illegal input?

I may have other questions when I hear your replies.

1 Like

G4P was created almost 11 years ago and no one has asked that question before and to be honest I never included that functionality LOL. Off the top of my head and without looking at the source code I suspect that will be an easy fix for the next version.

OK just looked at the source code and GEvent is an enumeration so the fix will not be easy or even possible without losing backward compatibility. Need to think about it.

Thanks for the replies :slight_smile:

Button Palette control :
1: b1 I guess is kind of the ‘index’ button to the contents of the palette.
It could be a fully functioning button or it could just be a placeholder with a symbol that indicates what the contents of the pallet are i.e. you don’t need to connect it to any event.
e.g. say we had a settings palette then we could have a small gear symbol at b1.

2: In my bodged up palette version, right clicking on any button in a palette will toggle the open/closed state of the palette. (hence asking about getting the mouse button + modifiers thru a GEvent)
I added a mouseButton and modifiers variables and then in
public void mouseEvent(MouseEvent event) {}
add
mouse_button = event.getButton();
and
modifiers = event.getModifiers();
Not the neatest solution probably but that means I could query those variables in the eventHandlers.

3: They don’t all have to be the same width, that’s just the way my version works and looks because i think it gives a nice organised feel, where it is quick and easy to find controls.
They could have different widths indeed.

4: Not really sure about the Vertical palette, I guess it could come in handy at some point.
The hardest thing I have found to get working nicely is (presuming a horizontal palette) the aligment of the buttons and which way the pallet opens depending on which side of the screen it is on.
If the pallet is positioned close to the left edge of screen and when open it expands to the right, all buttons are revealed and all good.
But if your pallet is on the right side of the screen, then when opened it needs to expand to the left and in order to preserve this b1(index) button position then button order needs to be juggled about.

5: The controls could be anything that realistically could be stuffed into the palette, I’m using buttons, toggles, checkboxes and number input fields. I guess there maybe some controls that maybe easier to use outside of a palette.

Number Field control :
1: I’m currently just using integer and decimal, though I guess others may have use for scientific ?

2: Umm… if by that you mean non numeric input, my version just ignores it,inside keyEvent() :
keyChar = e.getKey();
keyID = e.getAction();
and then :

if (keyChar >= '0' && keyChar <= '9') {
//deal with it
}

also checking for DELETE,BACKSPACE,etc
Very basic and bit clunky in terms of the keyinput to be honest.

Thought that may be the case with the enum.

ps. I can type pallet easy peasy, but have a mental block every time on palette :wink:

cheers,
mala

Getting the modifiers for events fired by G4P would prevent backward compatibility with earlier versions so I will not be implementing that because

  1. it would affect thousands of sketches created by thousands of users and no one else has asked for this in nearly 10 years.
  2. the right click is typically used to open a context sensitive help menu, so using it to open/close the palette is not intuitive.

So button 1 could be used simply to expand / close the palette?

If the palette width is less than the window width positioning it should not be a problem. The only difficulty is if the window is resizeable and the user shrinks the window too much (something else to consider)

It seems to me that we are looking at a special form of GPanel but where the tab is replaced by a button.

With regard to illegal numeric input all these are illegal
3…14159
123.56.7
12-3.456
0.45+09
also integers that exceed the limits of int or long set by Java.

I always have trouble deciding if palette has one or two l’s :grin:

Understood and appreciated, is there any other method/workaround that could be used ?

Yes but I’ve also found it very handy to have access to the functions of button 1 when the palette is closed, if button 1 is the most commonly used button in the palette. That way you don’t have to have the palette fully open to be able to use it e.g. to enter a value that is often changed.
If you are working with mostly a main view that for example has a load of 3D objects you are manipulating you want to reduce the amount of palettes that could obscure that main view.
Then again for most users perhaps as you say the answer is to have a version of GPanel where the tab is replaced with a button / icon and a horizontal opening style rather than the drop down.

I have been trying to delve deeper into writing my own library to achieve these things, after looking at whats going on in G4P.
I have learnt a lot by digging thru your code, thank you :star_struck: but I still have a mountain to climb !
Hence being lazy and asking about adding / extending classes.

If I was to implement such a control then I would need a requirements specification. This is one of the first stages in systems analysis and details what the user wants and the programmer provides. It is a chance for the user to say what functionality he/she expects and the programmer to say what is practicable.

So here is a first shot at one

Requirements specification for the GControlPalette

  1. The palette control would represent a rectangular area containing 1 or more G4P controls
  2. The control will have two principal parts, the tab and the panel.
  3. The controls would laid out either horizontally or vertically on the panel
  4. The panel will only be visible when the control is active
  5. The control is activated when the mouse passes over the tab part
  6. The control remains active (visible panel) while the mouse is over the tab or panel
  7. When visible the panel part will have a visual border and an optional opaque background
  8. The tab would be a small rectangular area containing text or an icon
  9. The tab would be positioned on the left of the panel for horizontal controls and the top of the panel for vertical controls
  10. The control can be moved by dragging the tab
  11. The panel size will be determined by the size of the controls added
  12. No provision will be made if the control’s width and/or height exceed the window’s width and/or height e.g. the window has been resized or too many controls have been added.

I can still think of many what-ifs but this seems a reasonable starting point. :relaxed:

That all sounds good to me.

5 & 6 : Why didn’t I think of this, that’s loads better than RMB… doh!
8: Could the width of the tab if using an icon be determined by the size of that icon ?
9: I would really like the option to be able to mirror the Palette, so that the tab is on the right and expands to the left, if possible. Making it easier to position on right side of screen.
Not saying it needs an option to do this when app is running, just when palette is initialised.

I know it might mean learning another library and I’m not sure if mine would fulfill all your needs but it certainly has room to expand the class without breaking.

Buttons are called

Button b = new Button( xpos,ypos,width,height,Label);

you can have a listbox, vertical or horizontal

listBox = l = new listBox(xpos,ypos,width,String [] Label)

listbox contain a menu class, which contains an array of buttons one for each string;
the index of each string is then accessible for evens either through menu.items.get(index).event(Object,Field);
or
l.event(index,Object,Field);

you can set verticality afterwards

with

l.vertical = true;

click is called as such,

b.click(Object,Field);

listbox event is called as such

l.click(index,Object,Field);

Its by all means not as advanced as g4p but its fully customizable.

Actuallythe menu class currently has a dropdown button option;

I think that would probably be the easiest to convert as its just a case of calling buttons to loop vertically.

Again,

image

menu on click

menu offclick

image

just converted the menu to allow verticality

image

just converted the menu to allow verticality

image

its been dropped down so to not interfere with the menu, but there it is.

Please note there is a lot of non menu code in here.

I have had many, many moments like that. Sometimes we get tunnel vision. :roll_eyes:

(8) is sensible and easy to implement
(9) Depends on what you mean by mirror. It is easy to make the panel appear either left or right of the tab and can be done dynamically at run-time depending on the position of the tab. If you mean to reverse the order of the G4P controls on the panel part, it would be possible but I am not keen because it produces an inconsistent interface for the user.

@paulgoux Thanks for the info on your library… there’s a lot going on in there!
I will probably stick with G4P for now as I’m reasonably familar with it and use various 2D/3D view functions as well, long term I will look at learning to write my own library as well.

With regard to (9) No need for the order of the G4P controls to be reversed, just having the option of the panel either left or right of the tab is enough :+1:
Presuming that would mean that position of the palette would be set by top left corner of the tab ?

I have modified items 8 & 9 inline with your comments. If you have further comments please let me know.

Requirements specification for the GControlPalette

  1. The palette control would represent a rectangular area containing 1 or more G4P controls
  2. The control will have two principal parts, the tab and the panel.
  3. The controls would laid out either horizontally or vertically on the panel
  4. The panel will only be visible when the control is active
  5. The control is activated when the mouse passes over the tab part
  6. The control remains active (visible panel) while the mouse is over the tab or panel
  7. When visible the panel part will have a visual border and an optional opaque background
  8. The tab would be a small rectangular area containing text or an icon. Its size would be the minimum needed to hold the text or image.
  9. The user can set the preferred side of the tab for the panel to appear. This preferred position would be used unless it means that part of the panel is off window.
  10. The control can be moved by dragging the tab
  11. The panel size will be determined by the size of the controls added
  12. No provision will be made if the control’s width and/or height exceed the window’s width and/or height e.g. the window has been resized or too many controls have been added.

Only one thing comes to mind at the moment :
(10) The Control can be moved by dragging tab…is it worth adding a position lock function ?

Trying to imagine how the dragging may work and how to avoid moving a palette by accident… say if you are dragging other things about that may be over/under a palette (possibly covered by ZOrdering anyway?)
Or as this would be a new Control could a key modifier be used with mouse drag?

This is available for GPanel, is easily added, so might as well have it. :relaxed:

It is possible that we could use the SHIFT or CTRL key as a modifier to determine whether the control could be dragged, but it shouldn’t be necessary. GControlPalette will be very similar to GPanel so try out the sketch below, drag the panels over each other etc and see if it performs as expected.

import g4p_controls.*;

public void setup(){
  size(480, 320, JAVA2D);
  createGUI();
}

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

public void createGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  surface.setTitle("Sketch Window");
  button1 = new GButton(this, 140, 30, 150, 67);
  button1.setText("Face text");
  panel1 = new GPanel(this, 50, 120, 100, 80, "Panel 1");
  panel1.setText("Panel 1");
  panel1.setOpaque(true);
  button2 = new GButton(this, 10, 30, 80, 40);
  button2.setText("Panel 1 button");
  panel1.addControl(button2);
  panel2 = new GPanel(this, 210, 120, 100, 80, "Panel 2");
  panel2.setText("Panel 2");
  panel2.setOpaque(true);
  button3 = new GButton(this, 10, 30, 80, 40);
  button3.setText("Panel 2 button");
  panel2.addControl(button3);
}

// Variable declarations 
// autogenerated do not edit
GButton button1; 
GPanel panel1; 
GButton button2; 
GPanel panel2; 
GButton button3; 

Have tried the sketch, must confess I have never used the GPanels before other than looking at examples.

The dragging does perform as expected, so modifiers not required.
Now though I have noticed that the Zordering does not perform as I presumed it might.

If you place one panel overlapping another panel and then click the top panels button, the button of the lower panel is also fired. I had a similar problem with my palette code, where an open pallett overlapped another button / object.
The only way I could find around it was to track if a pallet instance was active (mouse over)

A bit off subject : I can also see that which panel ends up on top when dragging one over the other depends on which was created first… possibly makes it easy to lose a small panel behind a larger one. (appreciate this is unlikely to be changed as would break a lot of sketches) What would be nice is if the selected panel that is being dragged was brought to the front always.

Z-ordering is a real pain to get right and eventually I will have to do some work to improve on whats there :smile:.

Anyway I have made a start today on the GControlPalette - early days but it is looking promising.