116 lines
4.8 KiB
C++
116 lines
4.8 KiB
C++
// gKeyMapper - the help window.
|
||
//
|
||
// One page, no scrolling and no search: the program has nine rows and four
|
||
// types, so the help is a handful of paragraphs. Each paragraph is one
|
||
// translated string including its bold term, so a translator sees the sentence
|
||
// the user sees.
|
||
|
||
#include "help.h"
|
||
|
||
#include <glib/gi18n.h>
|
||
|
||
namespace gkeymapper {
|
||
|
||
namespace {
|
||
|
||
GtkWidget* helpWindow = nullptr;
|
||
|
||
// One paragraph: Pango markup (the bold term), wrapped at a readable width.
|
||
GtkWidget* paragraph(const char* text) {
|
||
GtkWidget* label = gtk_label_new(nullptr);
|
||
gtk_label_set_markup(GTK_LABEL(label), text);
|
||
gtk_label_set_wrap(GTK_LABEL(label), TRUE);
|
||
gtk_label_set_max_width_chars(GTK_LABEL(label), 62);
|
||
gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
|
||
gtk_widget_set_halign(label, GTK_ALIGN_START);
|
||
return label;
|
||
}
|
||
|
||
void on_destroy(GtkWidget* /*widget*/, gpointer /*userData*/) {
|
||
helpWindow = nullptr;
|
||
}
|
||
|
||
const char* kParagraphs[] = {
|
||
N_("<b>The nine rows</b> – one per G key. Choose the type, then enter or capture the "
|
||
"target and press <i>Save mappings</i>."),
|
||
N_("<b>Key</b> – presses the captured sequence once, e.g. ctrl+c."),
|
||
N_("<b>Key (hold)</b> – presses it and keeps it down while the G key is held, e.g. for "
|
||
"push-to-talk. Only a single step can be held."),
|
||
N_("<b>Command</b> – runs a program or a command line, e.g. /usr/bin/firefox --new-window."),
|
||
N_("<b>Disabled</b> – the key does nothing."),
|
||
N_("<b>Capture</b> – records the keys you press next: press them, then <i>Done</i>. "
|
||
"Modifiers are kept (shift, altgr, …) and the names are layout independent, so ctrl+z "
|
||
"means the key that types z on your layout."),
|
||
N_("<b>Save mappings</b> – writes ~/.config/gKeyMapper/mappings.conf and makes the daemon "
|
||
"reload it. The menu entries <i>Export configuration...</i> and <i>Import "
|
||
"configuration...</i> do the same with a file you choose."),
|
||
N_("<b>Daemon status</b> – the footer shows whether gkeymapper-daemon is running, which "
|
||
"keyboard it found and the last G key that fired. <i>Options</i> shows the same in "
|
||
"more detail."),
|
||
N_("<b>Autostart</b> – <i>Start with the session</i> opens this window minimized to the tray "
|
||
"when you log in. The G keys work without it: gkeymapper-daemon (a user service) reads "
|
||
"them and replays the actions, and that daemon is the only part that has to run."),
|
||
N_("<b>Tray and window</b> – with <i>Minimize to tray</i> the window is hidden instead of "
|
||
"closed when you close or minimize it; the tray icon shows it again (<i>Show</i>) and "
|
||
"quits the program (<i>Close</i>). Starting gKeyMapper again closes the old window – "
|
||
"rows that were not saved yet come along."),
|
||
};
|
||
|
||
} // namespace
|
||
|
||
void show_help_window(GtkWindow* parent) {
|
||
if (helpWindow != nullptr) {
|
||
gtk_window_present(GTK_WINDOW(helpWindow));
|
||
return;
|
||
}
|
||
GtkWidget* window = gtk_window_new();
|
||
gtk_window_set_title(GTK_WINDOW(window), _("Help"));
|
||
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
|
||
// Themed like the main window: same icon, same resource path (registered by
|
||
// build_ui, which always runs before the menu can be used).
|
||
gtk_window_set_icon_name(GTK_WINDOW(window), "gkeymapper");
|
||
if (parent != nullptr) {
|
||
gtk_window_set_transient_for(GTK_WINDOW(window), parent);
|
||
}
|
||
|
||
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
|
||
gtk_widget_set_margin_top(box, 18);
|
||
gtk_widget_set_margin_bottom(box, 18);
|
||
gtk_widget_set_margin_start(box, 18);
|
||
gtk_widget_set_margin_end(box, 18);
|
||
gtk_window_set_child(GTK_WINDOW(window), box);
|
||
|
||
GtkWidget* heading = gtk_label_new(nullptr);
|
||
// The heading is the same word as the menu entry, only bigger; the markup is
|
||
// added around the translation so no translator has to carry tags for it.
|
||
g_autofree gchar* headingMarkup = g_strdup_printf("<big><b>%s</b></big>", _("Help"));
|
||
gtk_label_set_markup(GTK_LABEL(heading), headingMarkup);
|
||
gtk_label_set_xalign(GTK_LABEL(heading), 0.0f);
|
||
gtk_box_append(GTK_BOX(box), heading);
|
||
|
||
for (const char* text : kParagraphs) {
|
||
gtk_box_append(GTK_BOX(box), paragraph(_(text)));
|
||
}
|
||
|
||
GtkWidget* closeButton = gtk_button_new_with_label(_("Close window"));
|
||
gtk_widget_set_halign(closeButton, GTK_ALIGN_END);
|
||
g_signal_connect_swapped(closeButton, "clicked", G_CALLBACK(gtk_window_destroy), window);
|
||
gtk_box_append(GTK_BOX(box), closeButton);
|
||
|
||
g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), nullptr);
|
||
helpWindow = window;
|
||
gtk_window_present(GTK_WINDOW(window));
|
||
}
|
||
|
||
bool help_window_open() {
|
||
return helpWindow != nullptr;
|
||
}
|
||
|
||
void close_help_window() {
|
||
if (helpWindow != nullptr) {
|
||
gtk_window_destroy(GTK_WINDOW(helpWindow));
|
||
}
|
||
}
|
||
|
||
} // namespace gkeymapper
|