-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Help tool. #11045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Help tool. #11045
Conversation
I could take care for a wx implementation when this one is merged. |
I would just always use the GUI implementation... |
Btw. there's something that I don't like with either implementation: (Edit: point about Caps-Lock vs. Shift deleted; I got a wrong impression as my plot started with a full grid) |
Would it make sense to provide a general purpose popup-window as suggested [here]:(#9022 (comment))
Also, could the help tool display the currently used matplotlib version? And also the backend in use (if applicable)? |
If this is the direction that we adopt I prefer the general purpose pop-up
window.
In MEP27 all that is already implemented
https://matplotlib.org/devel/MEP/MEP27.html
If we don't want for one reason or another go with MEP27 right now. We can
always take some pieces
…On Sat, Apr 14, 2018, 2:02 PM Importance of Being Ernest, < ***@***.***> wrote:
Would it make sense to provide a general purpose popup-window as suggested
[here]:(#9022 (comment)
<#9022 (comment)>
)
Maybe there should be a general pupose popup child window in the
toolmanager [...]
This could then be used by the helper tool, but equally by all any other
tool that needs some window.
Also, could the help tool display the currently used matplotlib version?
And also the backend in use (if applicable)?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#11045 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABa86Qa3KBUwRQDClFZiEC0dKFbcaxlbks5tojm3gaJpZM4TTJGX>
.
|
I believe that no, as the end user you should just pick a GUI backend and learn how to pop up a window with it. There's no point in implementing and exposing a full compatibility layer between qt/gtk/wx/tk (well perhaps there is, but that's not Matplotlib), only the parts that we "reasonably" need (but that doesn't mean Matplotlib shouldn't be using native widgets when necessary). |
In this specific case the general pourpose pop-up is not for the user easy
of use. It is for us, we have to support several backends. If we think that
that belongs to the user, then we should not add this tool.
I agree with you that we shouldn't need to provide full wrapper around
qt,gtk,tk,etc... but we offer the backends and we add tools to them. So we
are shooting ourselves in the foot.
One very drastic idea that sometimes I fantasize with, is to get rid off
all the backends and just keep one and make the best set of tools ever. But
until we do that. We have to push for uniformity across what we have
committed to support
…On Sat, Apr 14, 2018, 5:22 PM Antony Lee, ***@***.***> wrote:
Would it make sense to provide a general purpose popup-window as suggested
[here]:(#9022 <#9022>
(comment))
I believe that no, as the end user you should just pick a GUI backend and
learn how to pop up a window with it. There's no point in implementing and
exposing a full compatibility layer between qt/gtk/wx/tk (well perhaps
there is, but that's not Matplotlib), only the parts that we "reasonably"
need (but that doesn't mean Matplotlib shouldn't be using native widgets
when necessary).
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#11045 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABa86emrqpKhuNk0ZY8u0FXDDeUJnoeQks5tomisgaJpZM4TTJGX>
.
|
If the thing is for our own internal use (as I think it should), then we don't need to overengineer it. By the day we'll want to have two tools that both pop up a dialog message (if that ever happens), we can refactor out that relevant part (and I would prefer a subclassing API rather than a tool-based one). |
That actually looks quite nice... (though not very space efficient). |
That's fine for the end user himself, although cumbersome. But what about the user that writes the program for the end user? What's great about the toolmanager approach is that it is really easy to add a some custom button in backend independent way. That leaves the end user the complete freedom of
|
Why exactly do you want that? At some point someone has to decide what toolkit to use. If I am writing a GUI app then the onus is on me to support all the toolkits I want to support. Obviously matplotlib has cross-backend support, but I think a line can reasonably drawn at "cross-backend support for plotting-related activities", and popping an arbitrary message window doesn't qualify. (Otherwise, where do you draw the line? Do we support OK/Cancel buttons with callbacks? Arbitrary input dialogs? etc.) Even if we were to go in this direction, I think the tool abstraction would be a pretty poor one for the action of popping up message dialogs. |
Sure, it's not matplotlib's task to provide GUI wrappers. Anectotical reason for providing a pop up (hidden not to distract from the PR features)
I have this program that me and collegues used to create reports about certain measurements. It would create a matplotlib figure and a text from some internally standarized data from a certain measurement device. The text would include some meta information like date/time of measurement, its duration, device's bandwidth setting etc. |
Because that becomes public API with bug reports, feature requests, deprecation periods and all that, which we do not want to handle (or rather speaking for myself: which I do not think anyone here should be wasting their time handling).
Then make your program call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coming back to topic: I support @DietmarSchwertberger in the comment that printed shortcuts should be the standard mixed-case notation (F1, Ctrl+W, Home) for special keys and composed shortcuts. Single character shortcuts (l, L) are case sensitive and must be written as they are. Can we just change the notation in the rc config or would we need a converter to preprocess them for displaying?
lib/matplotlib/backend_tools.py
Outdated
|
||
def _get_help_html(self): | ||
fmt = "<tr><td>{}</td><td>{}</td><td>{}</td></tr>" | ||
rows = [fmt.format("NAME", "KEYS", "DESCRIPTION")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use bold instead of uppercase, e.g. "<b>Name</b>"
instead of "NAME"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed that it looks better. Changed accordingly.
We need to check whether making them Ctrl-D in the rc would only case them to trigger on Ctrl+Shift+D or not... See also http://doc.qt.io/qt-5/qkeysequence.html#keyboard-layout-issues for fun issues :) |
10c1ecc
to
f79940d
Compare
Just checked with Qt5: The values in the rc are case sensitive: "home" works, "Home" does not. Which leaves us with formatting the displayed strings. Additional note: Not sure if this is a Qt issue or if this is within the matplotlib backend code (there's something going on with SPECIAL_KEYS, which may break with capitalization. Anyway, the formatting solution is just adding 4 lines of code, which is simple enough to not justify further research in the capitalization of rc shortcut settings. |
lib/matplotlib/backend_tools.py
Outdated
entries.append( | ||
"{}: {}\n\t{}".format( | ||
name, | ||
", ".join(self.toolmanager.get_tool_keymap(name)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For proper capitalization
", ".join(format_shortcut(key) for key in self.toolmanager.get_tool_keymap(name))
with
def format_shortcut(s):
def repl(match):
return '+'.join(g.capitalize() for g in match.groups() if g is not None)
return re.sub(r'(\w\w+)(?:\+(\w+))*', repl, s)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something like re.sub(r"\w+", lambda match: str.capitalize(match.group(0)), "ctrl+a")
seems simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this fails on single characters (a
-> A
should not be replaced, however ctrl+a
-> Ctrl+A
should).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aha...
lib/matplotlib/backend_tools.py
Outdated
for name, tool in sorted(self.toolmanager.tools.items()): | ||
if not tool.description: | ||
continue | ||
keys = ", ".join(self.toolmanager.get_tool_keymap(name)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keys = ", ".join(format_shortcut(key) for key in self.toolmanager.get_tool_keymap(name))
lib/matplotlib/backend_tools.py
Outdated
|
||
def _get_help_html(self): | ||
fmt = "<tr><td>{}</td><td>{}</td><td>{}</td></tr>" | ||
rows = [fmt.format("<b>Name</b>", "<b>Keys</b>", "<b>Description</b>")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use the terms "Action" and "Shortcuts" instead of "Name" and "Keys".
When testing I had to set |
yes (the idea is that the classic toolbar is going away... at some point) |
Should we also format the names? |
nah, these are actually entries into a dict |
Uh, oh! I just saw, there is |
@@ -963,10 +963,19 @@ def destroy(self, *args, **kwargs): | |||
self.window = None | |||
|
|||
|
|||
class HelpTk(backend_tools.ToolHelpBase): | |||
def trigger(self, *args): | |||
from tkinter.simpledialog import SimpleDialog |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the import at the beginning of the file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
lib/matplotlib/backend_tools.py
Outdated
keymaps = self.toolmanager.get_tool_keymap(name) | ||
# Capitalize "ctrl+a" -> "Ctrl+A" but leave "a" as is. | ||
return ", ".join(re.sub(r"\w{2,}|(?<=\+)\w", | ||
lambda m: m.group(0).capitalize(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as mentioned, ctrl+a
-> Ctrl+A
but also ctrl+A
-> Ctrl+Shift+A
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please push the fix directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anntzer I cannot push to your branch (permission denied). Either we have to resolve the permissions, or you can cherry pick from https://github.com/timhoffm/matplotlib/commits/anntzer/helptool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dunno why, I ticked the "allow edits from maintainers". In any case, I pulled it (thanks for the test) and further simplified format_shortcut (str.title is handy here...).
Do you want to add the GTK+ native widgets here? (though I'd like if we had some better grouping available.) |
Perhaps (as a stopgap before we can bikeshed how to do goruping) just keep the order in which the tools are inserted (adjusting the order for the iconless ones appropriately) and in two columns? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the way it looks, and works in all the supported backends
standard notation for displaying shortcuts, e.g. 'ctrl+a' -> 'Ctrl+A'. | ||
""" | ||
return (key_sequence if len(key_sequence) == 1 else | ||
re.sub(r"\+[A-Z]", r"+Shift\g<0>", key_sequence).title()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't add Shift for single letter shortcuts like 'L' for xscale; is that on purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I've been implicitly assuming that we keep the case sensitivity for single letters, i.e.
xscale k,L
yscale l
Now thinking about it, this is probably what we want to do. Otherwise, we'd have
xscale K, Shift+L
yscale L
This could be slightly misleading, because "L" really means only typing the L-Key, which in a text field would result in a lowercase "l". An alternative way out (similar to what the GtkShortcutWindow is doing) would be to enclose the keys.
xscale <K>, <Shift>+<L>
yscale <L>
Im +0.3 for sticking with the present solution.
Note: Shortcuts equal to single upper/lowercase letters are rarely used, because they clash with text input. I'm not aware of a standard notation for these cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vim just uses lowercase for lowercase and uppercase for uppercase (http://vimdoc.sourceforge.net/htmldoc/editing.html#CTRL-^), which seems just fine to me. ctrl+x are always documented as CTRL-X (UPPERCASE), but there are no shortcuts of the form ctrl+shift+x due to internal constraints.
PR Summary
Attn @fariza (@timhoffm perhaps as well).
This is an implementation of the help tool using native widgets. Note that only Qt can natively display tables (via html markup), for other backends I simply used
With that change, it is in fact shorter to provide 3 different native widget implementations (wx isn't there but I'm sure it would be just as easy to add once the general tool framework is merged) and add code to both generate plain text and html versions of the help text, than it is to set up the Table in #9022.
The relevant screenshots:
PR Checklist