Help, etc.
Updated 05 Apr 2018
|
Upper levels: - QuArK Information Base - 3. Advanced customization - 3.6. Plug-Ins - 3.6.1. Plugin Tutorial |
3.6.1.4. Help, etc. |
[ | - - ]
In this lesson we'll take on various help-related issues. |
Index |
Flyover help |
tiglari - 05 Apr 2018 | [ Top ] |
Help is the easiest. In the third position of qmenu.item, we can put a string which is displayed at the bottom-left of the screen when the cursor sits on the menu item. Or if the text is too long to be likely to fit into the window down there, begin it with a `|', then there's a message to press <F1> for help in the little window, and the string will appear in a popup window in the middle of the screen when <F1> is pressed. So we might replace our current menu-adding commands with something like this: quarkpy.mapcommands.items.append(quarkpy.qmenu.item("&Tag Side", tagSideClick, "|`Tags' the selected side so that another side can be snapped to it by a later `Glue to Tagged' command.\n\nJust the thing for making sure the legs of the table are actually touching the ground.")) quarkpy.mapcommands.items.append(quarkpy.qmenu.item("&Glue to Tagged", glueSideClick, "Snap selected to tagged side")) |
Disablers |
tiglari - 05 Apr 2018 | [ Top ] |
Now for something a bit harder, which is to cause the menu items to become `disabled' (light grey and unresponsive) when they can't do anything useful. The technique for doing this depends on the fact hat menu items are full-fledged objects and can have any kind of data attached to them. Furthermore there is an attribute `.state' with these values defined in quarkpy.qmenu.py: # menu state normal = 0 checked = 2 radiocheck = 3 disabled = 4 # can be added to the above default = 8 # can be added to the above These means first giving them names, then using those names when we append them to the command menu: mentagside = qmenu.item("&Tag Side", tagSideClick) menglueside = qmenu.item("&Glue to Tagged", glueSideClick) quarkpy.mapcommands.items.append(qmenu.sep) # separator quarkpy.mapcommands.items.append(mentagside) quarkpy.mapcommands.items.append(menglueside) Our next trick is a bit deeper. The `mapcommands' object in quarkpy has a `method' (some functions or procedures associated with the object), called `onclick', which does stuff when the commands menu is activated, before the items on it actually get displayed. What we're going to do is to redefine this method. Some code that does this is: def commandsclick(menu, oldcommand=quarkpy.mapcommands.onclick): oldcommand(menu) quarkpy.mapcommands.onclick = commandsclick But maybe I should first say a bit about what's really going on. In the running of a Python program, the first time a module is imported, the statements in it are executed. The def and class statements cause things to get defined, but you can write code to do anything you like. Subsequent imports of a module don't re-execute its statements, they just make the stuff defined in the module available, not only for `read' access, but also for `write' access (redefinition). This makes plugins extremely powerful, and is described in the Python documentation as a rather dangerous practice, but it seems to work out OK, the way it's managed in QuArK. But now what we want to do of course is check for the preconditions of our two menu items. For side-tagging, we want the selection to consist of exactly one side. If this is true, we want the menu state to be normal, otherwise disabled. Here's some code that does it: def selFace(editor): sel = editor.layout.explorer.sellist if len(sel)!=1 or sel[0].type!=":f": return None return sel[0] def commandsclick(menu, oldcommand=quarkpy.mapcommands.onclick): editor = mapeditor() if editor is None: return oldcommand(menu) mentagside.state = qmenu.normal sel = selFace(editor) if sel is None: mentagside.state = qmenu.disabled The next step is to extend commandsclick to test whether the gluing command is applicable. Working out all of the conditions is a bit tricky, here's something that seems to be OK: def commandsclick(menu, oldcommand=quarkpy.mapcommands.onclick): editor = mapeditor() if editor is None: return oldcommand(menu) mentagside.state = menglueside.state = qmenu.normal sel = selFace(editor) if sel is None: mentagside.state = qmenu.disabled menglueside.state = qmenu.disabled tagged = gettagged(editor) if tagged is None: menglueside.state = qmenu.disabled elif sel == tagged: menglueside.state = mentagside.state = qmenu.disabled It is also, in my experience, rather tricky to work out the conditions under which items should be disabled, & the code tends to get fragile. So it's good if the operations check that they're not going to cause trouble before proceeding. A further possibility is to dynamically adjust the hint, by writing code that says things like: hint = "|This menu item is disabled because ..."+hint[1:] A possible project would be to enhance the `tagging.py' module with some code that put into the tagging object info about the unsuccessful attempts to retrieve various kinds of tagged things; this info could then be used to add information to hints. |
Hot Keys |
tiglari - 05 Apr 2018 | [ Top ] |
Our last topic is something that's easy for us, but was very hard for Armin to implement, he says, `hot keys'. These are keys you can press to get an action instead of going thru the tedium of finding the relevant menu & the item on it. Here's how to set up a hot key: quarkpy.mapcommands.shortcuts["Ctrl+T"] = mentagside quarkpy.mapcommands.shortcuts["Ctrl+G"] = menglueside Note however that each shortcut key combo can only activiate one menu item, so a certain amount of cooperative behavior is desirable for plugin writers. I think it would be a cool and possibly feasable (but pretty hard) project to allow users to set up shortcuts the way they want them. Working example of stuff so far in maptagside2.py , as usual. |
Copyright (c) 2022, GNU General Public License by The QuArK (Quake Army Knife) Community - https://quark.sourceforge.io/ |
[ Top - ] | -