ControlP5 Scrollable list start closed - processing

Well i made an scrollable list in processing with the ControlP5 library.
I need an dropdown and the Dropdown has a lot of deprecated functions in it and there they say this is the way to do it know.
The problem I have is that whenever I run the sketch the scrollable list starts folded out (not just the bar but all the options out).
I initialize the scrolldown list like this
controlP5.addScrollableList("dropdown")
.setPosition(0, 0)
.setSize(200, 100)
.setBarHeight(10)
.setItemHeight(10)
.addItems(l)
.setType(ScrollableList.DROPDOWN)
;
Thanks in advance

You can set some default 'preselected' option
.setValue(1)
Or to fold in all options you can set inherited method setOpen() so your set up will looks like this
cp5.addScrollableList("dropdown")
.setPosition(100, 100)
.setSize(200, 100)
.setBarHeight(20)
.setItemHeight(20)
.addItems(l)
.setType(ScrollableList.DROPDOWN)
.setOpen(false) //false for closed
;
Hope it helps to achieve what you want because I'm not sure from your Q.

Related

Create PySimpleGUI list with a key

I wish to have a list of text items in a PySimpleGUI that I can update later. That is, I want to have a key for the list. This might be vertical or horizontal, and I do not know how many items there will be.
I end up with different use cases, but the current one is to make a single line of text items with different colors. Other times, I need to write and update a customized table, just different enough that the table widget does not work.
Conceptually, I want to do something like this:
layout = [ [sg.T('Titles and Things')], sg.ListThing(key='-data-', [[]]) ]
so that I can:
window['-data-'].update(values=[ [sg.T(v, color=c)] for (v,c) in my_data ])
Another, invalid syntax, way of saying what I want is to use [key="-data-", sg.T('Item1'), sg.T('Item2')].
Is this possible?
You can update individual layout elements but you cannot dynamically change the layout itself.
It is possible to create 2 or more elements, whereby only one of them is visible, and switch them later as needed. Or you can close and re-create the window with another layout. Or combine both approaches.
An example of switching layouts:
def change_layout():
left_col_1 = sg.Column([[sg.Text(f'Text {i}') for i in range(4)]], visible=True, key='col_1')
left_col_2 = sg.Column([[sg.Text(f'Text {i}')] for i in range(6)], visible=False, key='col_2')
visible_1 = True
layout = [[sg.Column([[left_col_1, left_col_2]]), sg.Button('Change layout', key='change')]]
window = sg.Window('window', layout=layout, finalize=True)
while True:
event, values = window.read()
print(event)
print(values)
print(visible_1)
if event in ('Exit', sg.WIN_CLOSED):
break
if event == 'change':
window['col_1'].update(visible=not visible_1)
window['col_2'].update(visible=visible_1)
visible_1 = not visible_1
Please notice that the alternative layouts for the left part (left_col_1, left_col_2) need to be enclosed in a container (column, frame) to keep their position in the window in the moment they are invisible.

Adding a check next to the selected item in tkinter OptionMenu

How could I add a check sign next to the currently selected item (or highlight it) in a OptionMenu in a tkinter GUI? The idea is that when I click again to select another item, I can see easily which one is selected (similar to the following picture)
I just added a new example:
from tkinter import *
OptionList = [
"Aries",
"Taurus",
"Gemini",
"Cancer"
]
app = Tk()
app.geometry('100x200')
variable = StringVar(app)
variable.set(OptionList[0])
opt = OptionMenu(app, variable, *OptionList)
opt.config(width=90, font=('Helvetica', 12))
opt.pack(side="top")
labelTest = Label(text="", font=('Helvetica', 12), fg='red')
labelTest.pack(side="top")
def callback(*args):
labelTest.configure(text="The selected item is {}".format(variable.get()))
variable.trace("w", callback)
app.mainloop()
Just use ttk widgets for this modern looking style, try saying something like:
from tkinter import ttk
....
#arguments - master variable default *values
opt = ttk.Optionmenu(app, variable, OptionList[0], *OptionList)
The effect given by this is pretty similar or maybe identical to what your trying to achieve.
You might notice an additional third positional argument here, it is actually default=OptionList[0] argument specified here(specific to just ttk.Optionmenu), it is just the default value that the optionmenu will display, ignoring this might lead to some bugs in the looks of optionmenu, like this.
And also keep in mind, it does not have a font option too. To overcome this, check this out
Hope this was of some help to you, do let me know if any errors or doubts.
Cheers
You can get similar effect using tk.OptionMenu:
from tkinter import *
OptionList = [
"Aries",
"Taurus",
"Gemini",
"Cancer"
]
app = Tk()
app.geometry('300x200')
variable = StringVar(app)
variable.set(OptionList[0])
opt = OptionMenu(app, variable, None) # need to supply at least one menu item
opt.config(width=90, font=('Helvetica', 12))
opt.pack(side="top")
# populate the menu items
menu = opt['menu']
menu.delete(0) # remove the None item
for item in OptionList:
menu.add_radiobutton(label=item, variable=variable)
labelTest = Label(text="", font=('Helvetica', 12), fg='red')
labelTest.pack(side="top")
def callback(*args):
labelTest.configure(text="The selected item is {}".format(variable.get()))
variable.trace("w", callback)
app.mainloop()

Scroll to selected row in GtkListBox

I'm a bit out of ideas here. I want a very simple thing: to be able to select a given GtkListBox row programmatically and then scroll the list box (which is wrapped in a ScrolledWindow and a Viewport).
Selecting a row is trivial (my code is Go & gotk3, but that's not so important):
listBox.SelectRow(row)
But scrolling to the row proved to be a real challenge. Whatever I tried, I failed:
I tried to focus the row, but it helped nothing
I tried to figure out the row's Y-coordinate using gtk_widget_translate_coordinates(), but it returns -1 for any row
Perhaps I can find out which row is at the top and the bottom of the list box and use that to scroll the ScrolledWindow but I can't figure out how to do that.
Update: I've tried what's proposed here: Manually scroll to a child in a Gtk.ScrolledWindow, but it didn't work as still no scrolling occurred:
listbox.SelectRow(rowToSelect)
listbox.SetFocusVAdjustment(listbox.GetAdjustment())
if rowToSelect != nil {
rowToSelect.GrabFocus()
}
I also tried the same with rowToSelect's child using the code below, to no avail:
if c, err := rowToSelect.GetChild(); err == nil {
c.GrabFocus()
}
I've finally nailed it thanks to the hint by Emmanuel Touzery. I didn't have to go as far as to use timers, but the problem was indeed that at the moment of filling of the list box the row hasn't been realised yet so no coordinate translation could possibly happen.
What I did is scheduled the scrolling using GLib's idle_add(), which makes it happen later downstream, and that seemed to have worked perfectly: see this commit for details.
In short, it all boils down to the following code:
func ListBoxScrollToSelected(listBox *gtk.ListBox) {
// If there's selection
if row := listBox.GetSelectedRow(); row != nil {
// Convert the row's Y coordinate into the list box's coordinate
if _, y, _ := row.TranslateCoordinates(listBox, 0, 0); y >= 0 {
// Scroll the vertical adjustment to center the row in the viewport
if adj := listBox.GetAdjustment(); adj != nil {
_, rowHeight := row.GetPreferredHeight()
adj.SetValue(float64(y) - (adj.GetPageSize()-float64(rowHeight))/2)
}
}
}
}
The above function has to be called using the glib.IdleAdd() and not in the code that fills the list box.
So, I had the same issue but managed to make it work in my case. I think there are good chances my solution will work for you too.
Since the grab_focus method didn't work, I started implementing a workaround solution using listbox_get_row_at_y. Highly unsatisfying, but hopefully it was going to work. And.. it didn't work, because get_row_at_y would always return null, for all the y values I'd feed it. And I knew the listbox wasn't empty. So that made me realize I was trying to focus a row that I had just been adding to the listbox.. The row wasn't realized yet, it couldn't be focused because it wasn't ready for that yet.
So I changed my code to fill the listbox, wait a 100ms timeout, and only then call grab_focus. And that worked!
I'm actually using a library which is wrapping the timeout call for me, but I think you could use g_timeout_add in 'raw' gtk for that purpose.
Note that this means that calling grab_focus on a listbox that was already filled beforehand and the items realized on screen should work directly. If that's your situation then this won't help you.

IUP, menu, webbrowser, tree, tabs

I have such menu situation:
int menu_create(Ihandle *menu)
{
hamburger = IupItem("&Hamburger", "hamburger");
IupSetAttributes(hamburger, "AUTOTOGGLE=YES, RADIO=YES");
char* ce = "Ćev&apčići";
cevapcici = IupItem(utf8_to_cp1250(ce), "cevapcici");
IupSetAttributes(cevapcici, "AUTOTOGGLE=YES, RADIO=YES");
exit = IupItem("Exit\tAlt+F4", "exit");
img4 = IupLoadImage("icons\\delete_16x16.ico");
IupSetAttributeHandle(exit, "TITLEIMAGE", img4);
menu = IupMenu(
IupSubmenu("File",
IupMenu(
hamburger,
cevapcici,
IupSeparator(),
IupItem("Carro&t", "carrot"),
IupSeparator(),
exit,
NULL)),
NULL);
IupSetFunction("exit", (Icallback)mnu_exit);
... etc...
IupSetHandle("menu", menu);
return IUP_DEFAULT;
}
How to get "radio toggle group" functionality with items hamburger and cevapcici so first turns off a second checkmark and opposite. This is my try but it don't work.
2) I try webbrowser example from IUP suite on my windows 7. Problem is that bad black flickering appear's during resize (increase). Also, background of webbrowser flicker black during showing.
I try a same example on Ubuntu and there flickering appear's too but it is not so much visible since background is there white.
Is here any way to get rid of those flickering or if not to get white background of webbrowser window on windows?
3) Since webbrowser is ole object (on windows) is it possible to use say "print preview" or "zoom" function by reference from IUP handle or at any other way like we used to do from MS programming tools?
wbInstance.ExecWB(Exec.OLECMDID_OPTICAL_ZOOM, ExecOpt.OLECMDEXECOPT_DONTPROMPTUSER, 150, DBNull.Value)
4) How can I get key_up event fired from IupTree?
5) Interesting situation with IupTabs:
frame3 = IupHbox(mat, val, NULL);
vboxt1 = IupVbox(frame3, NULL);
vboxt2 = IupVbox(frame3, NULL);
IupSetAttribute(vboxt1, "TABTITLE", "First documents... ");
IupSetAttribute(vboxt2, "TABTITLE", "Second documents... ");
tabs = IupTabs(vboxt1, vboxt2, NULL);
hbox1 = IupHbox(tabs, IupVbox(frame, tree, frame2, NULL), NULL);
dlg = IupDialog(hbox1);
When I set frame3 which should be a same for both tabs my GUI frozes.
However, I have to got same "mat" (IupMatrix) in both tabs because by changing tabs other data load in matrix but similar enough to use same matrix and related functions.
What to do here?
1) The RADIO attribute belongs to the IupMenu, not to the IupItem. This also means that all the IupItems inside that menu will be part of the radio.
A workaround would be to manually unset the other toggle inside the action callback.
2) That flicker is not caused by IUP. Don't know why the native controls are doing it.
3) Yes, but you will have to program that using the OLE API. If you take a look at the IupOleControl and IupWebBrower source code and send me the code to do it, I will be happy to add it to IUP.
4) You don't. Use the K_ANY callbacks.
5) You can not reuse a control in different places in any dialog. So you must have two different frames, with two different matrices. What you can do is to encapsulate your matrix, so the same function will create a matrix with the same attributes and callbacks any time you want one.

Jquery UI Slider - Input a Value and Slider Move to Location

I was wondering if anyone has found a solution or example to actually populating the input box of a slider and having it slide to the appropriate position onBlur() .. Currently, as we all know, it just updates this value with the position you are at. So in some regards, I am trying to reverse the functionality of this amazing slider.
One link I found: http://www.webdeveloper.com/forum/archive/index.php/t-177578.html is a bit outdated, but looks like they made an attempt. However, the links to the results do not exist. I am hoping that there may be a solution out there.
I know Filament has re-engineered the slider to handle select (drop down) values, and it works flawlessly.. So the goal would be to do the same, but with an input text box.
Will this do what you want?
$("#slider-text-box").blur(function() {
$("#slider").slider('option', 'value', parseInt($(this).val()));
});
Each option on the slider has a setter as well as a getter, so you can set the value with that, as in the example above. From the documentation:
//getter
var value = $('.selector').slider('option', 'value');
//setter
$('.selector').slider('option', 'value', 37);
UPDATE:
For dual sliders you'll need to use:
$("#amount").blur(function () {
$("#slider-range").slider("values", 0, parseInt($(this).val()));
});
$("#amount2").blur(function () {
$("#slider-range").slider("values", 1, parseInt($(this).val()));
});
You'll need to use Math.min/max to make sure that one value doesn't pass the other, as the setter doesn't seem to prevent this.
You were almost there when you were using the $("#slider-range").slider("values", 0) to get each value. A lot of jQuery has that kind of get/set convention in which the extra parameter is used to set the value.
I've done some work around the jQuery UI slider to make it accept values from a textbox, it may not be exactly what you were after but could help:
http://chowamigo.blogspot.com/2009/10/jquery-ui-slider-that-uses-text-box-for.html
$slider = $("#slider");
$("#amountMin").blur(function () {
$slider.slider("values", 0,Math.min($slider.slider("values", 1),parseInt($(this).val()) ) );
$(this).val(Math.min($slider.slider("values", 1),parseInt($(this).val())));
});
$("#amountMax").blur(function () {
$slider.slider("values",1,Math.max($slider.slider("values", 0),parseInt($(this).val()) ) );
$(this).val(Math.max($slider.slider("values", 0),parseInt($(this).val())));
});
I just used martin's code and updated the id to #slider also added the math.max as he suggested so the sliders won't overlap.

Resources