learning about @buttons

88 views
Skip to first unread message

Félix

unread,
Jul 11, 2020, 2:03:48 AM7/11/20
to leo-e...@googlegroups.com
I'm just learning about those @buttons by reading the mod_scripting 'readme' and trying to bring'em into leoInteg : 

if I understand correctly, you cannot just name any random node anywhere in an outline "@button hello" and expect to see a "hello" button appear in the top button bar upon saving, like you would expect a file to be generated, were you to name any node in an outline "@file myfile.txt", and save...

But closing Leo and reopening shows me the file with the button proudly sitting up there in the button bar :) Also having the node selected and clicking the already present 'script button' adds a button.

just wondering if i've got something off in my settings or is this normal behavior

I'm also reading about the @button having to be in a setting file or a @setting node ? but that would be to make them 'global' in all opened files if I got it right...?

Thanks! 

Félix

Félix

unread,
Jul 11, 2020, 2:07:49 AM7/11/20
to leo-editor
I guess my real question was : what (event) should trigger the button being defined as a "@button <label>" node, to appear in the button bar? 

Félix

unread,
Jul 11, 2020, 4:01:22 AM7/11/20
to leo-editor
f*ck it, :)  didnt wait for an anwser hehe: I Made @buttons a reality, merged it on the 'dev' branch, you guys tell me if it works for you. (log pane has a small delay in its refresh its normal)
G'night ! 
--
Félix

p.s. I may add more icons/eye candy to the buttons later when cleaning up for a new 0.1.13 release sometime before august.

Edward K. Ream

unread,
Jul 11, 2020, 6:30:28 AM7/11/20
to leo-editor
On Sat, Jul 11, 2020 at 1:03 AM Félix <felix...@gmail.com> wrote:

> if I understand correctly, you cannot just name any random node anywhere in an outline "@button hello" and expect to see a "hello" button appear in the top button bar upon saving, like you would expect a file to be generated, were you to name any node in an outline "@file myfile.txt", and save...

Correct.

> But closing Leo and reopening show me the file with the button proudly sitting up there in the button bar :) Also having the node selected and clicking the already present 'script button' adds a button.

Exactly.

> just wondering if i've got something off in my settings or is this normal behavior

This is the expected behavior.

>  what (event) should trigger the button being defined as a "@button <label>" node, to appear in the button bar?

There isn't any such event. You have to press the 'script button' button if you want to define the button immediately. Imo, this is reasonable because @button scripts also create commands. You don't want to do that by accident.

> I'm also reading about the @button having to be in a setting file or a @setting node ? but that would be to make them 'global' in all opened files if I got it right...?

Not quite. See the documentation in leoSettings.leo, the node @settings-->Common @button nodes

Edward

Edward K. Ream

unread,
Jul 11, 2020, 10:13:58 AM7/11/20
to leo-editor
On Saturday, July 11, 2020 at 3:01:22 AM UTC-5, Félix wrote:

> I Made @buttons a reality, merged it on the 'dev' branch, you guys tell me if it works for you.

Yes, it works.  gitk shows you did a lot of work.

How much of leo/plugins/mod_scripting.py did you use? Any of it?

If possible, I would prefer that mod_scripting.py be made gui agnostic. There is tricky logic in mod_scripting.py. Imo, it would be best if leoInteg uses that logic, via leoBridge. Maybe that already happens?

Which brings up a related question. Does it make sense to create an official "vs-code" gui? It be an unusual gui: it will (probably) delegate all gui operations to leoInteg.

What do you think, Félix?

Edward

Félix

unread,
Jul 11, 2020, 12:33:02 PM7/11/20
to leo-editor
Edward, I need more time and better comprehension of Leo's code in order to answer you question about a vscode gui. The way I see it, nullgui is perfectly fine.

Also, on a similar topic, leobridgeserver is meant to be agnostic and reused by anyone who wants to 'talk' to, or control leo via http websockets. So I wouldn't even say all that interaction with leo is 'vscode' specific.

I'll perfect it some more, and reconsider later if it should just be part of Leo instead of leoInteg.

Felix (on mobile, so no accent in the e)

Félix

unread,
Jul 11, 2020, 1:19:12 PM7/11/20
to leo-editor
Edward,

To shed some light on my implementation, here are the few lines it took on the leo/python side of things: 

def getButtons(self, p_package):
'''Gets the currently opened file's @buttons list'''
w_buttons = []
w_dict = self.commander.theScriptingController.buttonsDict

for w_key in w_dict:
w_entry = {"name": w_dict[w_key], "index": str(w_key)}
w_buttons.append(w_entry)

return self.sendLeoBridgePackage("buttons", w_buttons)

def clickButton(self, p_package):
'''Handles buttons clicked in vscode from the '@button' panel'''
w_index = p_package['index']
w_dict = self.commander.theScriptingController.buttonsDict
w_button = None
for w_key in w_dict:
if(str(w_key) == w_index):
w_button = w_key
w_button.command() # run clicked button command
return self.outputPNode(self.commander.p) # return selected node when done

Yes, it's a cowboy implementation and i should have had protected some of those lines with "if's" and try/catch blocks.

imma clean it up a bit and push back to dev in a few minutes. 

--
Félix (i'm home now)

Thomas Passin

unread,
Jul 11, 2020, 4:42:20 PM7/11/20
to leo-editor

On Saturday, July 11, 2020 at 2:03:48 AM UTC-4, Félix wrote:
I'm just learning about those @buttons by reading the mod_scripting 'readme' and trying to bring'em into leoInteg : 

...
I'm also reading about the @button having to be in a setting file or a @setting node ? but that would be to make them 'global' in all opened files if I got it right...?

Not necessarily, because you can have a @settings tree in any Leo outline.  @button commands in that local tree would be local to that outline.  That's good for experimenting, but it's easy to lose them when you start working with other outlines later in development, outlines that don't have those commands or buttons. You (or at least I, since it's happened to me) can forget where they are, or even that they exist.

Actually, you don't have to even have the @button nodes in an @settings tree.  Unless they are put into your MyLeoSettings outline (or LeoSettings), they will be local to the outline where you have their definition.

Edward K. Ream

unread,
Jul 11, 2020, 5:12:55 PM7/11/20
to leo-editor
On Saturday, July 11, 2020 at 12:19:12 PM UTC-5, Félix wrote:

To shed some light on my implementation, here are the few lines it took on the leo/python side of things: 

def getButtons(self, p_package):
'''Gets the currently opened file's @buttons list'''
w_buttons = []
w_dict = self.commander.theScriptingController.buttonsDict

for w_key in w_dict:
w_entry = {"name": w_dict[w_key], "index": str(w_key)}
w_buttons.append(w_entry)

return self.sendLeoBridgePackage("buttons", w_buttons)

def clickButton(self, p_package):
'''Handles buttons clicked in vscode from the '@button' panel'''
w_index = p_package['index']
w_dict = self.commander.theScriptingController.buttonsDict
w_button = None
for w_key in w_dict:
if(str(w_key) == w_index):
w_button = w_key
w_button.command() # run clicked button command
return self.outputPNode(self.commander.p) # return selected node when done

This is clever. It uses c.scriptingController.buttonsDict to get the required data. So yes, nothing more is needed on Leo's end.

I just now took a look at mod_scripting.py. Somehow I mis-remembered that it depended on the qt gui.  But it doesn't! Let's see what's going on:

1. The docstring says: "This plugin puts buttons in the icon area." No wonder I thought there was gui code involved.

2. sc.createIconButton attempts to creates each icon button this way:

b = self.iconBar.add(text=truncatedText, command=command, kind=kind)
if not b:
   
return None

ScriptingController.__init__ does:

self.iconBar = c.frame.getIconBarObject()

So sc.iconBar will either be None or a do-nothing object.  Either way, the code will work with any gui.

Yes, it's a cowboy implementation and i should have had protected some of those lines with "if's" and try/catch blocks.

I think it's very clever.

Eventually, there is no need now, I would like leoInteg to support right-clicking of the buttons. In Leo, this brings up a popup menu containing two items: "Remove Button" and "Goto Script".  Remove button can happen purely in leoInteg. However, the logic behind "Goto Script" is complicated.  Iirc, the AtButtonCallback class is involved. "Goto Script" can find the global scripts that are defined, say, in leoSettings.leo or myLeoSettings.leo that might not even be open.  Again, iirc.

Edward

Edward K. Ream

unread,
Jul 11, 2020, 5:16:57 PM7/11/20
to leo-editor
On Sat, Jul 11, 2020 at 11:33 AM Félix <felix...@gmail.com> wrote:
Edward, I need more time and better comprehension of Leo's code in order to answer you question about a vscode gui. The way I see it, nullgui is perfectly fine.

Also, on a similar topic, leobridgeserver is meant to be agnostic and reused by anyone who wants to 'talk' to, or control leo via http websockets. So I wouldn't even say all that interaction with leo is 'vscode' specific.

I now see what you did with buttons. As I said in the other reply, it looks good to me. I agree that no vscode-specific code is required for buttons.

More generally, the trick you used to "peek" into c.scriptingController.buttonsDict might be applied in other situations...

Edward

Félix

unread,
Jul 12, 2020, 3:12:06 PM7/12/20
to leo-editor
Edward,

I didn't mention it last night, but the dev branch now has right-click on @buttons to remove them, but finding their 'source' node was not available on the 'button' object kept in the button dict. unless i'm mistaken. I'll put this feature on the no-rush-todo list for now. :) 

Félix

Edward K. Ream

unread,
Jul 13, 2020, 4:50:13 AM7/13/20
to leo-editor
On Sun, Jul 12, 2020 at 2:12 PM Félix <felix...@gmail.com> wrote:

I didn't mention it last night, but the dev branch now has right-click on @buttons to remove them, but finding their 'source' node was not available on the 'button' object kept in the button dict. unless i'm mistaken. I'll put this feature on the no-rush-todo list for now. :) 

Good work. Finding the source can wait until much later.

Edward
Reply all
Reply to author
Forward
0 new messages