237 lines
6.7 KiB
JavaScript
237 lines
6.7 KiB
JavaScript
|
|
/* DING: Desktop Icons New Generation for GNOME Shell
|
|
*
|
|
* Copyright (C) Gtk4 port 2022, 2025 Sundeep Mediratta (smedius@gmail.com)
|
|
* Copyright (C) 2019 Sergio Costas (rastersoft@gmail.com)
|
|
* Based on code original (C) Carlos Soriano
|
|
* SwitcherooControl code based on code original from Marsch84
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, version 3 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
import {_} from '../dependencies/gettext.js';
|
|
import {Gdk, Gio, Graphene, Gtk, Gsk, GLib} from '../dependencies/gi.js';
|
|
import * as DesktopIconItem from './desktopIconItem.js';
|
|
|
|
export {StackItem};
|
|
|
|
const Signals = imports.signals;
|
|
|
|
const StackItem = class extends DesktopIconItem.DesktopIconItem {
|
|
constructor(desktopManager, file, attributeContentType, fileTypeEnum) {
|
|
super(desktopManager, fileTypeEnum);
|
|
this._isSpecial = false;
|
|
this._file = file;
|
|
this.isStackTop = true;
|
|
this.stackUnique = false;
|
|
this._size = null;
|
|
this._modifiedTime = null;
|
|
this._attributeContentType = attributeContentType;
|
|
this._createIconActor();
|
|
this._createStackTopIcon();
|
|
const stackName = this._file;
|
|
/** TRANSLATORS: when using a screen reader,
|
|
* this is the text read when a stack is
|
|
* selected. Example: if a stack named "pictures"
|
|
* is selected, it will say "Stack pictures" */
|
|
const accessibleName = _('Stack');
|
|
this._setLabelName(stackName);
|
|
this.container.update_property(
|
|
[Gtk.AccessibleProperty.LABEL],
|
|
[`${accessibleName} ${stackName}`]
|
|
);
|
|
this._savedCoordinates = null;
|
|
}
|
|
|
|
_createStackedAttributeContentTypeIcon() {
|
|
const stackIcon = Gtk.Snapshot.new();
|
|
/* A shadow for the pile of icons gives a sense of floating. */
|
|
const stackShadow = {
|
|
color: {red: 0, green: 0, blue: 0, alpha: 0.15},
|
|
dx: 2,
|
|
dy: 0,
|
|
radius: 1,
|
|
};
|
|
/* A slight shadow swhich makes each icon in the stack look separate. */
|
|
const iconShadow = {
|
|
color: {red: 0, green: 0, blue: 0, alpha: 0.30},
|
|
dx: 1,
|
|
dy: 0,
|
|
radius: 1,
|
|
};
|
|
const numberOfIcons = 5;
|
|
let yOffset = 0;
|
|
let xOffset = this.unStacked ? 8 : 4;
|
|
const icon = Gio.content_type_get_icon(this._attributeContentType);
|
|
const theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default());
|
|
const scale = this._icon.get_scale_factor();
|
|
let iconPaintable = null;
|
|
try {
|
|
iconPaintable = theme.lookup_by_gicon(
|
|
icon,
|
|
this.Prefs.IconSize,
|
|
scale, Gtk.TextDirection.NONE,
|
|
Gtk.IconLookupFlags.FORCE_SIZE
|
|
);
|
|
} catch (e) {
|
|
iconPaintable = theme.lookup_icon(
|
|
'image-missing',
|
|
[],
|
|
this.Prefs.IconSize,
|
|
scale,
|
|
Gtk.TextDirection.NONE,
|
|
Gtk.IconLookupFlags.FORCE_SIZE
|
|
);
|
|
}
|
|
const stackIconArray = Array(numberOfIcons).fill(iconPaintable);
|
|
const w = iconPaintable.get_intrinsic_width();
|
|
const h = iconPaintable.get_intrinsic_height();
|
|
let X = xOffset * numberOfIcons;
|
|
let Y = yOffset;
|
|
|
|
stackIcon.translate(new Graphene.Point({x: X, y: Y}));
|
|
stackIcon.push_shadow([new Gsk.Shadow(stackShadow)]);
|
|
|
|
stackIconArray.forEach(paintableWidget => {
|
|
// Position each widget from right to left
|
|
X = -xOffset;
|
|
stackIcon.translate(new Graphene.Point({x: X, y: Y}));
|
|
stackIcon.push_shadow([new Gsk.Shadow(iconShadow)]);
|
|
|
|
// Render the paintable widget
|
|
paintableWidget.snapshot(stackIcon, w, h);
|
|
|
|
stackIcon.pop(); // Remove shadow effect for the next widget
|
|
});
|
|
// Remove the initial transformation & shadow
|
|
stackIcon.pop();
|
|
|
|
return stackIcon.to_paintable(null);
|
|
}
|
|
|
|
_createStackTopIcon() {
|
|
const stackIcon = this._createStackedAttributeContentTypeIcon();
|
|
const iconPaintable = this._addEmblemsToIconIfNeeded(stackIcon);
|
|
this._icon.set_paintable(iconPaintable);
|
|
}
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
_doButtonOnePressed(button, X, Y, x, y, shiftPressed, controlPressed) {
|
|
const variant = GLib.Variant.new('s', this.attributeContentType);
|
|
this._desktopManager.mainApp.activate_action(
|
|
'stackunstack',
|
|
variant
|
|
);
|
|
}
|
|
|
|
setSelected() {
|
|
this.container.grab_focus();
|
|
}
|
|
|
|
unsetSelected() {
|
|
this.keyboardUnSelected();
|
|
}
|
|
|
|
updateIcon() {
|
|
this._createStackTopIcon();
|
|
}
|
|
|
|
_addEmblemsToIconIfNeeded(iconPaintable) {
|
|
let emblem = null;
|
|
|
|
if (this.isStackTop && !this.stackUnique)
|
|
emblem = Gio.ThemedIcon.new('icon-emblem-stack');
|
|
|
|
return this._addEmblem(iconPaintable, emblem);
|
|
}
|
|
|
|
/** *********************
|
|
* Getters and setters *
|
|
***********************/
|
|
|
|
get attributeContentType() {
|
|
return this._attributeContentType;
|
|
}
|
|
|
|
get displayName() {
|
|
return this._file;
|
|
}
|
|
|
|
get file() {
|
|
return this._file;
|
|
}
|
|
|
|
get fileName() {
|
|
return this._file;
|
|
}
|
|
|
|
get fileSize() {
|
|
return this._size;
|
|
}
|
|
|
|
get isAllSelectable() {
|
|
return false;
|
|
}
|
|
|
|
get modifiedTime() {
|
|
return this._modifiedTime;
|
|
}
|
|
|
|
get path() {
|
|
return `/tmp/${this._file}`;
|
|
}
|
|
|
|
get uri() {
|
|
return `file:///tmp/${this._file}`;
|
|
}
|
|
|
|
get isStackMarker() {
|
|
return true;
|
|
}
|
|
|
|
get savedCoordinates() {
|
|
return this._savedCoordinates;
|
|
}
|
|
|
|
get unStacked() {
|
|
return this.Prefs.UnstackList.includes(this._attributeContentType);
|
|
}
|
|
|
|
get x() {
|
|
return this._x1;
|
|
}
|
|
|
|
get y() {
|
|
return this._y1;
|
|
}
|
|
|
|
get X() {
|
|
return this._savedCoordinates[0];
|
|
}
|
|
|
|
get Y() {
|
|
return this._savedCoordinates[1];
|
|
}
|
|
|
|
set size(size) {
|
|
this._size = size;
|
|
}
|
|
|
|
set time(time) {
|
|
this._modifiedTime = time;
|
|
}
|
|
|
|
set savedCoordinates(pos) {
|
|
}
|
|
};
|
|
Signals.addSignalMethods(StackItem.prototype);
|