[gnome-characters/bilelmoussaoui/gtk4] character dialog: redesign & cleanup
- From: Bilal Elmoussaoui <bilelmoussaoui src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-characters/bilelmoussaoui/gtk4] character dialog: redesign & cleanup
- Date: Mon, 22 Nov 2021 13:17:41 +0000 (UTC)
commit 42c0a0d46a8a90058b31fa8dc59f0aad33296d3a
Author: Bilal Elmoussaoui <bil elmoussaoui gmail com>
Date: Mon Nov 22 14:06:12 2021 +0100
character dialog: redesign & cleanup
- Move from a GtkDialog to a AdwWindow, there's nothing we need from GtkDialog's api
- Cleanup both UI file & the code
- Rename the UI file according to the JS file
data/character.ui | 150 -----------------------
data/character_dialog.ui | 172 +++++++++++++++++++++++++++
data/meson.build | 2 +-
data/org.gnome.Characters.data.gresource.xml | 2 +-
data/style.css | 18 ---
src/characterDialog.js | 172 +++++++++++----------------
6 files changed, 241 insertions(+), 275 deletions(-)
---
diff --git a/data/character_dialog.ui b/data/character_dialog.ui
new file mode 100644
index 0000000..c95431b
--- /dev/null
+++ b/data/character_dialog.ui
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="Gjs_CharacterDialog" parent="AdwWindow">
+ <property name="default-width">360</property>
+ <property name="default-height">500</property>
+ <child>
+ <object class="AdwToastOverlay" id="toastOverlay">
+ <property name="child">
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkHeaderBar">
+ <child type="start">
+ <object class="GtkRevealer" id="revealer">
+ <property name="transition-type">crossfade</property>
+ <child>
+ <object class="GtkButton">
+ <property name="icon-name">go-previous-symbolic</property>
+ <property name="action-name">character.go-back</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <property name="title-widget">
+ <object class="AdwWindowTitle" id="windowTitle" />
+ </property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="mainStack">
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">character</property>
+ <property name="child">
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="halign">fill</property>
+ <property name="valign">center</property>
+ <child>
+ <object class="GtkStack" id="characterStack">
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">character</property>
+ <property name="child">
+ <object class="GtkLabel" id="characterLabel">
+ <property name="ellipsize">end</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <style>
+ <class name="character-label" />
+ </style>
+ </object>
+ </property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">missing</property>
+ <property name="child">
+ <object class="GtkLabel" id="missingLabel">
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="wrap">True</property>
+ <property name="wrap-mode">word</property>
+ <property name="width-chars">28</property>
+ <property name="max-width-chars">28</property>
+ <property name="justify">center</property>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="margin-top">18</property>
+ <property name="margin-bottom">18</property>
+ <property name="halign">center</property>
+ <property name="label" translatable="yes">_Copy Character</property>
+ <property name="use-underline">true</property>
+ <property name="action-name">character.copy</property>
+ <style>
+ <class name="pill" />
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="AdwClamp">
+ <property name="margin-top">18</property>
+ <property name="margin-bottom">18</property>
+ <property name="margin-start">18</property>
+ <property name="margin-end">18</property>
+ <property name="vexpand">True</property>
+ <property name="valign">center</property>
+ <child>
+ <object class="GtkListBox">
+ <property name="selection-mode">none</property>
+ <child>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Unicode</property>
+ <child>
+ <object class="GtkLabel" id="detailLabel">
+ <property name="selectable">True</property>
+ <style>
+ <class name="dim-label" />
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="seeAlsoRow">
+ <property name="use-underline">true</property>
+ <property name="title" translatable="yes">_See Also</property>
+ <property name="action-name">character.see-also</property>
+ <property name="activatable">true</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <style>
+ <class name="boxed-list" />
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">related</property>
+ <property name="child">
+ <object class="GtkScrolledWindow" id="related-scrolled">
+ <property name="hscrollbar-policy">never</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="AdwClamp">
+ <property name="margin-top">36</property>
+ <property name="margin-bottom">36</property>
+ <property name="margin-start">18</property>
+ <property name="margin-end">18</property>
+ <property name="vexpand">True</property>
+ <property name="valign">center</property>
+ <child>
+ <object class="GtkListBox" id="relatedListbox">
+ <style>
+ <class name="boxed-list" />
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </child>
+ </template>
+</interface>
+
+
diff --git a/data/meson.build b/data/meson.build
index 9855260..abd70fa 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -9,7 +9,7 @@ resource_data = files(
'icons/hicolor/scalable/categories/characters-picture-symbolic.svg',
'icons/hicolor/scalable/categories/characters-punctuation-symbolic.svg',
'style.css',
- 'character.ui',
+ 'character_dialog.ui',
'characters_view.ui',
'menu.ui',
'shortcuts.ui',
diff --git a/data/org.gnome.Characters.data.gresource.xml b/data/org.gnome.Characters.data.gresource.xml
index e9d4b31..116d834 100644
--- a/data/org.gnome.Characters.data.gresource.xml
+++ b/data/org.gnome.Characters.data.gresource.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/Characters">
- <file preprocess="xml-stripblanks">character.ui</file>
+ <file preprocess="xml-stripblanks">character_dialog.ui</file>
<file preprocess="xml-stripblanks">characters_view.ui</file>
<file preprocess="xml-stripblanks" alias="gtk/help-overlay.ui">shortcuts.ui</file>
<file preprocess="xml-stripblanks">menu.ui</file>
diff --git a/data/style.css b/data/style.css
index 4d8f419..d9ceb22 100644
--- a/data/style.css
+++ b/data/style.css
@@ -19,26 +19,8 @@ Gjs_MenuPopover GtkScrolledWindow {
font-size: x-large;
}
-.character-list {
- color: @theme_text_color;
- background-color: @theme_base_color;
-}
-
.character-label {
font-size: 7em;
font-weight: bold;
}
-.detail-label {
- font-size: small;
-}
-
-.related .character {
- font-size: 3em;
-}
-
-.related .list-row {
- border-style: groove;
- border-width: 2pt;
-}
-
diff --git a/src/characterDialog.js b/src/characterDialog.js
index ff46f49..d45da7c 100644
--- a/src/characterDialog.js
+++ b/src/characterDialog.js
@@ -17,54 +17,49 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-const { Gc, GLib, Gio, GObject, Gtk, Pango } = imports.gi;
+const { Adw, Gc, Gdk, Gio, GObject, Gtk, Pango } = imports.gi;
const Util = imports.util;
var CharacterDialog = GObject.registerClass({
-
Signals: {
'character-copied': { param_types: [GObject.TYPE_STRING] },
},
- Template: 'resource:///org/gnome/Characters/character.ui',
- InternalChildren: ['main-stack', 'character-stack',
- 'character-label', 'missing-label', 'detail-label',
- 'copy-button', 'copy-revealer', 'related-listbox'],
-}, class CharacterDialog extends Gtk.Dialog {
+ Template: 'resource:///org/gnome/Characters/character_dialog.ui',
+ InternalChildren: [
+ 'mainStack', 'characterStack',
+ 'characterLabel', 'missingLabel', 'detailLabel',
+ 'seeAlsoRow', 'relatedListbox',
+ 'windowTitle', 'revealer', 'toastOverlay',
+ ],
+}, class CharacterDialog extends Adw.Window {
_init(character, fontDescription) {
- super._init({
- use_header_bar: true,
- width_request: 400,
- height_request: 400,
- });
-
+ super._init();
this._cancellable = new Gio.Cancellable();
+ this._fontDescription = fontDescription;
- this._copy_button.connect('clicked', () => this._copyCharacter());
-
- this._related_listbox.connect('row-selected', (listBox, row) => this._handleRowSelected(listBox,
row));
-
- this._relatedButton = new Gtk.ToggleButton({ label: _('See Also') });
- this.add_action_widget(this._relatedButton, Gtk.ResponseType.HELP);
- this._relatedButton.show();
+ const actions = new Gio.SimpleActionGroup();
+ Util.initActions(actions, [
+ { name: 'copy', activate: this._copyCharacter.bind(this) },
+ { name: 'see-also', activate: this._seeMore.bind(this) },
+ { name: 'go-back', activate: this._seeCharacter.bind(this) },
+ ]);
+ this.insert_action_group('character', actions);
- this._relatedButton.connect('toggled', () => {
- if (this._main_stack.visible_child_name === 'character')
- this._main_stack.visible_child_name = 'related';
- else
- this._main_stack.visible_child_name = 'character';
- });
-
- this._fontDescription = fontDescription;
this._setCharacter(character);
-
- this._copyRevealerTimeoutId = 0;
}
_finishSearch(result) {
- let children = this._related_listbox.get_children();
- for (let index in children)
- this._related_listbox.remove(children[index]);
+ let children = this._relatedListbox.get_first_child();
+ while (children !== null) {
+ let nextChild = children.get_next_sibling();
+ if (nextChild === null) {
+ this._relatedListbox.remove(children);
+ break;
+ }
+
+ this._relatedListbox.remove(nextChild);
+ }
for (let index = 0; index < result.len; index++) {
let uc = Gc.search_result_get(result, index);
@@ -72,30 +67,24 @@ var CharacterDialog = GObject.registerClass({
if (name === null)
continue;
- let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL });
-
- let characterLabel = new Gtk.Label({ label: uc,
+ let row = new Adw.ActionRow();
+ row.set_title(Util.capitalize(name));
+ row.add_prefix(new Gtk.Label({
+ label: uc,
valign: Gtk.Align.CENTER,
halign: Gtk.Align.CENTER,
- width_request: 45 });
- characterLabel.add_css_class('character');
- hbox.pack_start(characterLabel, false, false, 2);
-
- let nameLabel = new Gtk.Label({ label: Util.capitalize(name),
- halign: Gtk.Align.START,
- ellipsize: Pango.EllipsizeMode.END });
- hbox.pack_start(nameLabel, true, true, 0);
-
- let row = new Gtk.ListBoxRow();
- row._character = uc;
- row.add(hbox);
- row.show_all();
-
- this._related_listbox.add(row);
+ width_request: 45,
+ }));
+ let gesture = new Gtk.GestureClick();
+ gesture.connect('pressed', () => {
+ this._setCharacter(uc);
+ this._seeCharacter();
+ });
+ row.add_controller(gesture);
+ row.set_activatable(true);
+ this._relatedListbox.append(row);
}
-
- this._relatedButton.visible =
- this._related_listbox.get_children().length > 0;
+ this._seeAlsoRow.visible = result.len > 0;
}
_setCharacter(uc) {
@@ -108,30 +97,27 @@ var CharacterDialog = GObject.registerClass({
if (name !== null)
name = Util.capitalize(name);
else
- name = _('Unicode U+%04s').format(codePointHex);
-
+ name = 'U+%04s'.format(codePointHex);
- let headerBar = this.get_header_bar();
- headerBar.title = name;
+ this._windowTitle.title = name;
+ this._characterLabel.label = this._character;
+ this._detailLabel.label = 'U+%04s'.format(codePointHex);
- this._character_label.override_font(this._fontDescription);
- this._character_label.label = this._character;
+ let pangoContext = this._characterLabel.get_pango_context();
+ pangoContext.set_font_description(this._fontDescription);
- var pangoContext = this._character_label.get_pango_context();
var pangoLayout = Pango.Layout.new(pangoContext);
pangoLayout.set_text(this._character, -1);
if (pangoLayout.get_unknown_glyphs_count() === 0) {
- this._character_stack.visible_child_name = 'character';
+ this._characterStack.visible_child_name = 'character';
} else {
var fontFamily = this._fontDescription.get_family();
- this._missing_label.label =
+ this._missingLabel.label =
// TRANSLATORS: the first variable is a character, the second is a font
_('%s is not included in %s').format(name, fontFamily);
- this._character_stack.visible_child_name = 'missing';
+ this._characterStack.visible_child_name = 'missing';
}
- this._detail_label.label = _('Unicode U+%04s').format(codePointHex);
-
this._cancellable.cancel();
this._cancellable.reset();
let criteria = Gc.SearchCriteria.new_related(this._character);
@@ -148,54 +134,30 @@ var CharacterDialog = GObject.registerClass({
}
});
- this._relatedButton.active = false;
- this._main_stack.visible_child_name = 'character';
- this._main_stack.show_all();
+ this._seeAlsoRow.visible = false;
}
- _hideCopyRevealer() {
- if (this._copyRevealerTimeoutId > 0) {
- GLib.source_remove(this._copyRevealerTimeoutId);
- this._copyRevealerTimeoutId = 0;
- this._copy_revealer.set_reveal_child(false);
- }
+ _seeMore() {
+ this._revealer.reveal_child = true;
+ this._mainStack.visible_child_name = 'related';
}
- _clipboardOwnerChanged(clipboard) {
- let text = clipboard.wait_for_text();
- if (text !== this._character)
- this._hideCopyRevealer();
+ _seeCharacter() {
+ this._revealer.reveal_child = false;
+ this._mainStack.visible_child_name = 'character';
}
_copyCharacter() {
- if (this._clipboard === null) {
- this._clipboard = Gc.gtk_clipboard_get();
- let clipboardOwnerChanged =
- this._clipboard.connect('owner-change', clipboard => this._clipboardOwnerChanged(clipboard));
- this.connect('destroy', () => this._clipboard.disconnect(clipboardOwnerChanged));
- }
- this._clipboard.set_text(this._character, -1);
+ let display = Gdk.Display.get_default();
+ let clipboard = display.get_clipboard();
+
+ clipboard.set(this._character);
this.emit('character-copied', this._character);
- // Show a feedback message with a revealer. The message is
- // hidden after 2 seconds, or when another client set a
- // different text to clipboard.
- this._hideCopyRevealer();
- this._copy_revealer.set_reveal_child(true);
- this._copyRevealerTimeoutId =
- GLib.timeout_add(GLib.PRIORITY_DEFAULT, 2000, () => this._hideCopyRevealer());
- this.connect('destroy', () => {
- if (this._copyRevealerTimeoutId > 0)
- GLib.source_remove(this._copyRevealerTimeoutId);
+ const toast = new Adw.Toast({
+ title: _('Character copied to clipboard'),
+ timeout: 2,
});
- }
-
- _handleRowSelected(listBox, row) {
- if (row !== null) {
- this._setCharacter(row._character);
- let toplevel = this.get_transient_for();
- let action = toplevel.lookup_action('character');
- action.activate(new GLib.Variant('s', row._character));
- }
+ this._toastOverlay.add_toast(toast);
}
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]