[gnome-shell/gbsneto/folders-as-dialogs: 6/9] appDisplay: Add folder title and entry to dialog
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/gbsneto/folders-as-dialogs: 6/9] appDisplay: Add folder title and entry to dialog
- Date: Mon, 20 Jan 2020 20:29:11 +0000 (UTC)
commit a612d087652e8beb25a2ed51ceb2af5523a16ca8
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Tue Dec 17 16:39:24 2019 -0300
appDisplay: Add folder title and entry to dialog
This allows editing the folder name, and keeps the folder title visible
at all times.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/896
data/theme/gnome-shell-sass/widgets/_app-grid.scss | 27 ++++
js/ui/appDisplay.js | 142 ++++++++++++++++++++-
2 files changed, 166 insertions(+), 3 deletions(-)
---
diff --git a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
index f5467bbd6d..42aeadc192 100644
--- a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
+++ b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
@@ -90,6 +90,33 @@ $app_grid_fg_color: #fff;
border-radius: 8px;
spacing: 24px;
background-color: transparentize(darken($osd_bg_color,10%), 0.05);
+
+ & .folder-name-container {
+ padding: 12px 18px;
+ spacing: 12px;
+
+ & .folder-name-label,
+ & .folder-name-entry {
+ font-size: 18pt;
+ font-weight: bold;
+ }
+
+ & .folder-name-entry { width: 300px }
+
+ /* FIXME: this is to keep the label in sync with the entry */
+ & .folder-name-label { padding: 5px 7px }
+
+ & .edit-folder-button {
+ @extend %button;
+
+ padding: 0;
+ width: 36px;
+ height: 36px;
+ border-radius: 18px;
+
+ & > StIcon { icon-size: 16px }
+ }
+ }
}
.app-folder-dialog-container {
padding: 12px;
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index e1be5abdd9..855e952244 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -1630,7 +1630,7 @@ var FolderIcon = GObject.registerClass({
if (this._dialog)
return;
if (!this._dialog) {
- this._dialog = new AppFolderDialog(this);
+ this._dialog = new AppFolderDialog(this, this._folder);
this._parentView.addFolderDialog(this._dialog);
this._dialog.connect('open-state-changed', (popup, isOpen) => {
if (!isOpen)
@@ -1818,7 +1818,7 @@ var AppFolderDialog = GObject.registerClass({
'open-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
},
}, class AppFolderDialog extends St.Widget {
- _init(source) {
+ _init(source, folder) {
super._init({
layout_manager: new Clutter.BinLayout(),
style_class: 'app-folder-dialog-container',
@@ -1834,6 +1834,7 @@ var AppFolderDialog = GObject.registerClass({
}));
this._source = source;
+ this._folder = folder;
this._view = source.view;
this._isOpen = false;
@@ -1845,8 +1846,11 @@ var AppFolderDialog = GObject.registerClass({
y_expand: true,
x_align: Clutter.ActorAlign.FILL,
y_align: Clutter.ActorAlign.FILL,
+ vertical: true,
});
this.add_child(this._viewBox);
+
+ this._addFolderNameEntry();
this._viewBox.add_child(this._view);
global.focus_manager.add_group(this);
@@ -1861,6 +1865,131 @@ var AppFolderDialog = GObject.registerClass({
this._needsZoomAndFade = false;
}
+ _addFolderNameEntry() {
+ this._entryBox = new St.BoxLayout({
+ style_class: 'folder-name-container',
+ });
+ this._viewBox.add_child(this._entryBox);
+
+ // Empty actor to center the title
+ let ghostButton = new Clutter.Actor();
+ this._entryBox.add_child(ghostButton);
+
+ let stack = new Shell.Stack({
+ x_expand: true,
+ x_align: Clutter.ActorAlign.CENTER,
+ });
+ this._entryBox.add_child(stack);
+
+ // Folder name label
+ this._folderNameLabel = new St.Label({
+ style_class: 'folder-name-label',
+ x_expand: true,
+ y_expand: true,
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.CENTER,
+ });
+
+ stack.add_child(this._folderNameLabel);
+
+ // Folder name entry
+ this._entry = new St.Entry({
+ style_class: 'folder-name-entry',
+ opacity: 0,
+ reactive: false,
+ });
+ this._entry.clutter_text.set({
+ x_expand: true,
+ x_align: Clutter.ActorAlign.CENTER,
+ });
+
+ this._entry.clutter_text.connect('activate', () => {
+ this._showFolderLabel();
+ });
+
+ stack.add_child(this._entry);
+
+ // Edit button
+ let button = new St.Button({
+ style_class: 'edit-folder-button',
+ button_mask: St.ButtonMask.ONE,
+ toggle_mode: true,
+ reactive: true,
+ can_focus: true,
+ x_align: Clutter.ActorAlign.END,
+ y_align: Clutter.ActorAlign.CENTER,
+ child: new St.Icon({
+ icon_name: 'document-edit-symbolic',
+ icon_size: 16,
+ }),
+ });
+
+ button.connect('notify::checked', () => {
+ if (button.checked)
+ this._showFolderEntry();
+ else
+ this._showFolderLabel();
+ });
+
+ this._entryBox.add_child(button);
+
+ ghostButton.add_constraint(new Clutter.BindConstraint({
+ source: button,
+ coordinate: Clutter.BindCoordinate.SIZE,
+ }));
+
+ this._folder.connect('changed::name', () => this._syncFolderName());
+ this._syncFolderName();
+ }
+
+ _syncFolderName() {
+ let newName = _getFolderName(this._folder);
+
+ this._folderNameLabel.text = newName;
+ this._entry.text = newName;
+ }
+
+ _switchActor(from, to) {
+ to.reactive = true;
+ to.ease({
+ opacity: 255,
+ duration: 300,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+
+ from.ease({
+ opacity: 0,
+ duration: 300,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ onComplete: () => {
+ from.reactive = false;
+ },
+ });
+ }
+
+ _showFolderLabel() {
+ this._maybeUpdateFolderName();
+ this._switchActor(this._entry, this._folderNameLabel);
+ }
+
+ _showFolderEntry() {
+ this._switchActor(this._folderNameLabel, this._entry);
+
+ this._entry.clutter_text.set_selection(0, -1);
+ this._entry.clutter_text.grab_key_focus();
+ }
+
+ _maybeUpdateFolderName() {
+ let folderName = _getFolderName(this._folder);
+ let newFolderName = this._entry.text.trim();
+
+ if (newFolderName.length === 0 || newFolderName === folderName)
+ return;
+
+ this._folder.set_string('name', newFolderName);
+ this._folder.set_boolean('translate', false);
+ }
+
_zoomAndFadeIn() {
let [sourceX, sourceY] =
this._source.get_transformed_position();
@@ -1945,7 +2074,13 @@ var AppFolderDialog = GObject.registerClass({
vfunc_allocate(box, flags) {
let contentBox = this.get_theme_node().get_content_box(box);
- this._view.adaptToSize(contentBox.get_width(), contentBox.get_height());
+
+ let [, entryBoxHeight] = this._entryBox.get_size();
+ let spacing = this._viewBox.layout_manager.spacing;
+
+ this._view.adaptToSize(
+ contentBox.get_width(),
+ contentBox.get_height() - entryBoxHeight - spacing);
super.vfunc_allocate(box, flags);
@@ -2028,6 +2163,7 @@ var AppFolderDialog = GObject.registerClass({
return;
this._zoomAndFadeOut();
+ this._showFolderLabel();
this._grabHelper.ungrab({ actor: this });
this._isOpen = false;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]