ags steal

This commit is contained in:
2023-10-29 15:05:17 +01:00
parent e7416f5bdf
commit 912479c43d
101 changed files with 10639 additions and 1 deletions

View File

@@ -0,0 +1,245 @@
// Not yet used. For cool drag and drop stuff. Thanks DevAlien
const Toggles = {};
Toggles.Wifi = NetworkToggle;
Toggles.Bluetooth = BluetoothToggle;
Toggles.DND = DNDToggle;
Toggles.ThemeToggle = ThemeToggle;
Toggles.ProfileToggle = ProfileToggle;
// Toggles.Record = RecordToggle;
// Toggles.Airplane = AirplaneToggle;
// Toggles.DoNotDisturb = DoNotDisturbToggle;
const TARGET = [Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.SAME_APP, 0)];
export class ActionCenter extends Gtk.Box {
static {
GObject.registerClass({
GTypeName: 'ActionCenter',
Properties: {
},
}, this);
}
constructor({ className = "ActionCenter", toggles, ...rest }) {
super(rest);
this.toggles = Toggles
this.currentToggles = Settings.getSetting("toggles", []);
this.mainFlowBox = this._setupFlowBox(className + QSView.editing && className + "Editing");
this.mainFlowBox.connect("drag_motion", this._dragMotionMain);
this.mainFlowBox.connect("drag_drop", this._dragDropMain);
this._dragged = {};
this._draggedExtra = {};
this._dragged;
this._currentPosition = 0;
this._orderedState;
this._draggedName;
this.updateList(toggles, this.mainFlowBox)
this.set_orientation(Gtk.Orientation.VERTICAL);
this.add(this.mainFlowBox)
this.mainFlowBox.set_size_request(1, 30)
if (QSView.editing) {
this.extraFlowBox = this._setupFlowBox(className);
this.extraFlowBox.connect("drag_motion", this._dragMotionExtra);
this.extraFlowBox.connect("drag_drop", this._dragDropExtra);
this.updateList(this._getExtraToggles(), this.extraFlowBox)
this.add(Box({
vertical: true,
children: [
Label("Extra widgets"),
Label("Drop here to remove or drag from here to add"),
this.extraFlowBox
]
}))
}
}
_getExtraToggles() {
let toggles = { ...this.toggles }
this.currentToggles.map(t => {
if (toggles[t]) {
delete toggles[t];
}
});
return Object.keys(toggles);
}
_setupFlowBox(className) {
const flowBox = new Gtk.FlowBox();
flowBox.set_valign(Gtk.Align.FILL);
flowBox.set_min_children_per_line(2);
flowBox.set_max_children_per_line(2);
flowBox.set_selection_mode(Gtk.SelectionMode.NONE);
flowBox.get_style_context().add_class(className);
flowBox.set_homogeneous(true);
flowBox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
return flowBox;
}
createWidget = (name, index, type) => {
const editSetup = (widget) => {
widget.drag_source_set(
Gdk.ModifierType.BUTTON1_MASK,
TARGET,
Gdk.DragAction.COPY
);
widget.connect("drag-begin", (w, context) => {
const widgetContainer = widget.get_parent();
Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(widgetContainer));
this._dragged = {
widget: widgetContainer.get_parent().get_parent(),
container: widgetContainer,
name: name,
currentPosition: type === "Main" ? index : null,
currentPositionExtra: type === "Extra" ? index : null,
from: type,
}
widgetContainer.get_style_context().add_class("hidden");
if (type !== "Main") {
this.extraFlowBox.remove(this._dragged.widget);
}
return true;
});
widget.connect("drag-failed", () => {
this.updateList(Settings.getSetting("toggles"), this.mainFlowBox)
this.updateList(this._getExtraToggles(), this.extraFlowBox)
});
}
let row = new Gtk.FlowBoxChild({ visible: true });
row.add(Toggles[name]({ setup: QSView.editing && editSetup, QSView: QSView }));
row._index = index;
row._name = name;
return row;
}
updateList(toggles, flowBox) {
let type = flowBox === this.mainFlowBox ? "Main" : "Extra"
var childrenBox = flowBox.get_children();
childrenBox.forEach((element) => {
flowBox.remove(element);
element.destroy();
});
if (!toggles) return;
toggles.forEach((name, i) => {
if (Toggles[name])
flowBox.add(this.createWidget(name, i, type));
});
flowBox.show_all();
}
_dragMotionMain = (widget, context, x, y, time) => {
if (this._dragged.currentPositionExtra !== null) {
this._dragged.currentPositionExtra = null;
if (this._isChild(this.extraFlowBox, this._dragged.widget)) {
this.extraFlowBox.remove(this._dragged.widget);
}
}
const children = this.mainFlowBox.get_children();
const sampleItem = children[0];
const sampleWidth = sampleItem.get_allocation().width;
const sampleHeight = sampleItem.get_allocated_height();
const perLine = Math.floor(this.mainFlowBox.get_allocation().width / sampleWidth);
const pos = Math.floor(y / sampleHeight) * perLine + Math.floor(x / sampleWidth);
if (pos >= children.length && pos !== 0) return false;
if (this._dragged.currentPosition === null) {
this.mainFlowBox.insert(this._dragged.widget, pos);
this._dragged.currentPosition = pos;
} else if (this._dragged.currentPosition !== pos) {
if (this._isChild(this.mainFlowBox, this._dragged.widget)) {
this.mainFlowBox.remove(this._dragged.widget);
}
this.mainFlowBox.insert(this._dragged.widget, pos);
this._dragged.currentPosition = pos;
}
return true;
}
_dragDropMain = () => {
if (this._dragged.from !== "Main") {
this.currentToggles.splice(this._dragged.currentPosition, 0, this._dragged.name);
} else {
const indexCurrentToggle = this.currentToggles.indexOf(this._dragged.name);
this.currentToggles.splice(indexCurrentToggle, 1);
this.currentToggles.splice(this._dragged.currentPosition, 0, this._dragged.name);
}
Settings.setSetting("toggles", this.currentToggles);
this._dragged.container.get_style_context().remove_class("hidden");
return true;
}
_dragDropExtra = () => {
if (this._dragged.from === "Main") {
const indexCurrentToggle = this.currentToggles.indexOf(this._dragged.name);
this.currentToggles.splice(indexCurrentToggle, 1);
}
Settings.setSetting("toggles", this.currentToggles);
this._dragged.container.get_style_context().remove_class("hidden");
return true;
}
_dragMotionExtra = (widget, context, x, y, time) => {
if (this._dragged.currentPosition !== null) {
this._dragged.currentPosition = null;
if (this._isChild(this.mainFlowBox, this._dragged.widget)) {
this.mainFlowBox.remove(this._dragged.widget);
}
}
const children = this.extraFlowBox.get_children();
const sampleItem = children[0];
let pos = 0;
if (sampleItem) {
const sampleWidth = sampleItem.get_allocation().width;
const sampleHeight = sampleItem.get_allocated_height();
const perLine = Math.floor(this.extraFlowBox.get_allocation().width / sampleWidth);
pos = Math.floor(y / sampleHeight) * perLine + Math.floor(x / sampleWidth);
}
if (pos >= children.length && pos !== 0) return false;
if (this._dragged.currentPositionExtra === null) {
this.extraFlowBox.insert(this._dragged.widget, pos);
this._dragged.currentPositionExtra = pos;
}
if (this._dragged.currentPositionExtra !== pos) {
if (this._isChild(this.extraFlowBox, this._dragged.widget)) {
this.extraFlowBox.remove(this._dragged.widget);
}
this.extraFlowBox.insert(this._dragged.widget, pos);
this._dragged.currentPositionExtra = pos;
}
return true;
}
_isChild(container, widget) {
let found = false;
container.get_children().forEach((c) => {
if (c === widget) found = true;
})
return found;
}
}

View File

@@ -0,0 +1,74 @@
const { Gdk, Gtk } = imports.gi;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
import { Utils, Widget } from '../../imports.js';
// min-height for diameter
// min-width for trough stroke
// padding for space between trough and progress
// margin for space between widget and parent
// background-color for trough color
// color for progress color
// font size for progress value (0-100px) (hacky i know, but i want animations)
// TODO: border-radius for rounded ends maybe (unimportant)
export const AnimatedCircProg = (props) => Widget({
...props,
type: Gtk.DrawingArea,
setup: (area) => {
const styleContext = area.get_style_context();
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
area.connect('draw', Lang.bind(area, (area, cr) => {
const styleContext = area.get_style_context();
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
const progressValue = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 100.0;
const bg_stroke = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const fg_stroke = bg_stroke - padding;
const radius = Math.min(width, height) / 2.0 - Math.max(bg_stroke, fg_stroke) / 2.0;
const center_x = width / 2.0 + marginLeft;
const center_y = height / 2.0 + marginTop;
const start_angle = -Math.PI / 2.0;
const end_angle = start_angle + (2 * Math.PI * progressValue);
const start_x = center_x + Math.cos(start_angle) * radius;
const start_y = center_y + Math.sin(start_angle) * radius;
const end_x = center_x + Math.cos(end_angle) * radius;
const end_y = center_y + Math.sin(end_angle) * radius;
// Draw background
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
cr.arc(center_x, center_y, radius, 0, 2 * Math.PI);
cr.setLineWidth(bg_stroke);
cr.stroke();
// Draw progress
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
cr.arc(center_x, center_y, radius, start_angle, end_angle);
cr.setLineWidth(fg_stroke);
cr.stroke();
// Draw rounded ends for progress arcs
cr.setLineWidth(0);
cr.arc(start_x, start_y, fg_stroke / 2, 0, 0 - 0.01);
cr.fill();
cr.arc(end_x, end_y, fg_stroke / 2, 0, 0 - 0.01);
cr.fill();
}))
},
})

View File

@@ -0,0 +1,10 @@
const { Gdk, Gtk } = imports.gi;
import { Widget } from '../../imports.js';
export const ContextMenuItem = ({ label, onClick }) => Widget({
type: Gtk.MenuItem,
label: `${label}`,
setup: menuItem => {
menuItem.connect("activate", onClick);
}
})

View File

@@ -0,0 +1,70 @@
const { Gdk, Gtk } = imports.gi;
const CLICK_BRIGHTEN_AMOUNT = 0.13;
export function setupCursorHover(button) {
var clicked = false;
var dummy = false;
var cursorX = 0;
var cursorY = 0;
const styleContext = button.get_style_context();
var clickColor = styleContext.get_property('background-color', Gtk.StateFlags.HOVER);
clickColor.green += CLICK_BRIGHTEN_AMOUNT;
clickColor.blue += CLICK_BRIGHTEN_AMOUNT;
clickColor.red += CLICK_BRIGHTEN_AMOUNT;
clickColor = clickColor.to_string();
const display = Gdk.Display.get_default();
button.connect('enter-notify-event', () => {
const cursor = Gdk.Cursor.new_from_name(display, 'pointer');
button.get_window().set_cursor(cursor);
});
button.connect('leave-notify-event', () => {
const cursor = Gdk.Cursor.new_from_name(display, 'default');
button.get_window().set_cursor(cursor);
});
// button.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
// button.connect('motion-notify-event', (widget, event) => {
// [dummy, cursorX, cursorY] = event.get_coords(); // Get the mouse coordinates relative to the widget
// if(!clicked) widget.style = `
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%);
// `;
// });
// button.connect('button-press-event', (widget, event) => {
// clicked = true;
// [dummy, cursorX, cursorY] = event.get_coords(); // Get the mouse coordinates relative to the widget
// cursorX = Math.round(cursorX); cursorY = Math.round(cursorY);
// widget.style = `
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%);
// `;
// widget.toggleClassName('growingRadial', true);
// widget.style = `
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 70%, ${clickColor} 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%);
// `
// });
// button.connect('button-release-event', (widget, event) => {
// widget.toggleClassName('growingRadial', false);
// widget.toggleClassName('fadingRadial', false);
// widget.style = `
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%);
// `
// clicked = false;
// });
}
export function setupCursorHoverAim(button) {
button.connect('enter-notify-event', () => {
const display = Gdk.Display.get_default();
const cursor = Gdk.Cursor.new_from_name(display, 'crosshair');
button.get_window().set_cursor(cursor);
});
button.connect('leave-notify-event', () => {
const display = Gdk.Display.get_default();
const cursor = Gdk.Cursor.new_from_name(display, 'default');
button.get_window().set_cursor(cursor);
});
}

View File

@@ -0,0 +1,7 @@
import { Widget } from '../../imports.js';
export const MaterialIcon = (icon, size, props = {}) => Widget.Label({
className: `icon-material txt-${size}`,
label: icon,
...props,
})

View File

@@ -0,0 +1,73 @@
const { Gdk, Gtk } = imports.gi;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
import { Utils, Widget } from '../../imports.js';
// min-height/min-width for height/width
// background-color/color for background/indicator color
// padding for pad of indicator
// font-size for selected index (0-based)
export const NavigationIndicator = (count, vertical, props) => Widget({
...props,
type: Gtk.DrawingArea,
setup: (area) => {
const styleContext = area.get_style_context();
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
area.set_size_request(width, height);
area.connect('draw', Lang.bind(area, (area, cr) => {
const styleContext = area.get_style_context();
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
// console.log('allocated width/height:', area.get_allocated_width(), '/', area.get_allocated_height())
area.set_size_request(width, height);
const paddingLeft = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const paddingRight = styleContext.get_padding(Gtk.StateFlags.NORMAL).right;
const paddingTop = styleContext.get_padding(Gtk.StateFlags.NORMAL).top;
const paddingBottom = styleContext.get_padding(Gtk.StateFlags.NORMAL).bottom;
const selectedCell = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
let cellWidth = width;
let cellHeight = height;
if (vertical) cellHeight /= count;
else cellWidth /= count;
const indicatorWidth = cellWidth - paddingLeft - paddingRight;
const indicatorHeight = cellHeight - paddingTop - paddingBottom;
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
cr.setLineWidth(2);
// Background
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
cr.rectangle(0, 0, width, height);
cr.fill();
// The indicator line
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
if (vertical) {
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
cr.stroke();
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
cr.fill();
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth / 2, Math.PI, 2 * Math.PI);
cr.fill();
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorHeight - indicatorWidth / 2, indicatorWidth / 2, 0, Math.PI);
cr.fill();
}
else {
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
cr.stroke();
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
cr.fill();
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorWidth - indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
}))
},
})

View File

@@ -0,0 +1,298 @@
// This file is for the actual widget for each single notification
const { GLib, Gdk, Gtk } = imports.gi;
import { Utils, Widget } from '../../imports.js';
const { lookUpIcon, timeout } = Utils;
const { Box, EventBox, Icon, Scrollable, Label, Button, Revealer } = Widget;
import { MaterialIcon } from "./materialicon.js";
import { setupCursorHover } from "./cursorhover.js";
const NotificationIcon = (notifObject) => {
// { appEntry, appIcon, image }, urgency = 'normal'
if (notifObject.image) {
return Box({
valign: 'center',
hexpand: false,
className: 'notif-icon',
style: `
background-image: url("${notifObject.image}");
background-size: auto 100%;
background-repeat: no-repeat;
background-position: center;
`,
});
}
let icon = 'NO_ICON';
if (lookUpIcon(notifObject.appIcon))
icon = notifObject.appIcon;
if (lookUpIcon(notifObject.appEntry))
icon = notifObject.appEntry;
return Box({
valign: 'center',
hexpand: false,
className: 'notif-icon',
setup: box => {
if (icon != 'NO_ICON') box.pack_start(Icon({
icon, size: 30,
halign: 'center', hexpand: true,
valign: 'center',
setup: () => {
box.toggleClassName(`notif-icon-material-${notifObject.urgency}`, true);
},
}), false, true, 0);
else box.pack_start(MaterialIcon(`${notifObject.urgency == 'critical' ? 'release_alert' : 'chat'}`, 'hugeass', {
hexpand: true,
setup: () => box.toggleClassName(`notif-icon-material-${notifObject.urgency}`, true),
}), false, true, 0)
}
});
};
export default ({
notifObject,
isPopup = false,
props = {},
} = {}) => {
const command = (isPopup ?
() => notifObject.dismiss() :
() => notifObject.close()
)
const destroyWithAnims = () => {
widget.sensitive = false;
notificationBox.setStyle(rightAnim1);
Utils.timeout(200, () => {
wholeThing.revealChild = false;
});
Utils.timeout(400, () => {
command();
wholeThing.destroy();
});
}
const widget = EventBox({
onHover: (self) => {
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
if (!wholeThing._hovered)
wholeThing._hovered = true;
},
onHoverLost: (self) => {
self.window.set_cursor(null);
if (wholeThing._hovered)
wholeThing._hovered = false;
if(isPopup) {
command();
}
},
onMiddleClick: (self) => {
destroyWithAnims();
}
});
const wholeThing = Revealer({
properties: [
['id', notifObject.id],
['close', undefined],
['hovered', false],
['dragging', false],
['destroyWithAnims', () => destroyWithAnims]
],
revealChild: false,
transition: 'slide_down',
transitionDuration: 200,
child: Box({ // Box to make sure css-based spacing works
homogeneous: true,
})
});
const display = Gdk.Display.get_default();
const notificationContent = Box({
...props,
className: `${isPopup ? 'popup-' : ''}notif-${notifObject.urgency} spacing-h-10`,
children: [
NotificationIcon(notifObject),
Box({
valign: 'center',
vertical: true,
hexpand: true,
children: [
Box({
children: [
Label({
xalign: 0,
className: 'txt-small txt-semibold titlefont',
justify: Gtk.Justification.LEFT,
hexpand: true,
maxWidthChars: 24,
ellipsize: 3,
wrap: true,
useMarkup: notifObject.summary.startsWith('<'),
label: notifObject.summary,
}),
]
}),
Label({
xalign: 0,
className: 'txt-smallie notif-body-${urgency}',
useMarkup: true,
xalign: 0,
justify: Gtk.Justification.LEFT,
wrap: true,
label: notifObject.body,
}),
]
}),
Box({
className: 'spacing-h-5',
children: [
Label({
valign: 'center',
className: 'txt-smaller txt-semibold',
justify: Gtk.Justification.RIGHT,
setup: (label) => {
const messageTime = GLib.DateTime.new_from_unix_local(notifObject.time);
if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year()) {
label.label = messageTime.format('%H:%M');
}
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year() - 1) {
label.label = messageTime.format('%H:%M\nYesterday');
}
else {
label.label = messageTime.format('%H:%M\n%d/%m');
}
}
}),
Button({
className: 'notif-close-btn',
onClicked: () => {
destroyWithAnims()
},
child: MaterialIcon('close', 'large', {
valign: 'center',
}),
setup: (button) => setupCursorHover(button),
}),
]
}),
// what is this? i think it should be at the bottom not on the right
// Box({
// className: 'actions',
// children: actions.map(action => Button({
// className: 'action-button',
// onClicked: () => Notifications.invoke(id, action.id),
// hexpand: true,
// child: Label(action.label),
// })),
// }),
]
})
// Gesture stuff
const gesture = Gtk.GestureDrag.new(widget);
var initialDir = 0;
// in px
const startMargin = 0;
const dragThreshold = 100;
// in rem
const maxOffset = 10.227;
const endMargin = 20.455;
const disappearHeight = 6.818;
const leftAnim1 = `transition: 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: -${Number(maxOffset + endMargin)}rem;
margin-right: ${Number(maxOffset + endMargin)}rem;
opacity: 0;`;
const rightAnim1 = `transition: 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: ${Number(maxOffset + endMargin)}rem;
margin-right: -${Number(maxOffset + endMargin)}rem;
opacity: 0;`;
const notificationBox = Box({
properties: [
['leftAnim1', leftAnim1],
['rightAnim1', rightAnim1],
['ready', false],
],
homogeneous: true,
children: [notificationContent],
connections: [
[gesture, self => {
var offset = gesture.get_offset()[1];
if (initialDir == 0 && offset != 0)
initialDir = (offset > 0 ? 1 : -1)
if (offset > 0) {
if (initialDir < 0)
self.setStyle(`margin-left: 0px; margin-right: 0px;`);
else
self.setStyle(`
margin-left: ${Number(offset + startMargin)}px;
margin-right: -${Number(offset + startMargin)}px;
`);
}
else if (offset < 0) {
if (initialDir > 0)
self.setStyle(`margin-left: 0px; margin-right: 0px;`);
else {
offset = Math.abs(offset);
self.setStyle(`
margin-right: ${Number(offset + startMargin)}px;
margin-left: -${Number(offset + startMargin)}px;
`);
}
}
wholeThing._dragging = Math.abs(offset) > 10;
if (widget.window)
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
}, 'drag-update'],
[gesture, self => {
if (!self._ready) {
wholeThing.revealChild = true;
self._ready = true;
return;
}
const offset = gesture.get_offset()[1];
if (Math.abs(offset) > dragThreshold && offset * initialDir > 0) {
if (offset > 0) {
self.setStyle(rightAnim1);
widget.sensitive = false;
}
else {
self.setStyle(leftAnim1);
widget.sensitive = false;
}
Utils.timeout(200, () => {
wholeThing.revealChild = false
});
Utils.timeout(400, () => {
command();
wholeThing.destroy();
});
}
else {
self.setStyle(`transition: margin 200ms cubic-bezier(0.05, 0.7, 0.1, 1), opacity 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: ${startMargin}px;
margin-right: ${startMargin}px;
margin-bottom: unset; margin-top: unset;
opacity: 1;`);
if (widget.window)
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
wholeThing._dragging = false;
}
initialDir = 0;
}, 'drag-end'],
],
})
widget.add(notificationBox);
wholeThing.child.children = [widget];
return wholeThing;
}

View File

@@ -0,0 +1,51 @@
import { Widget } from '../../imports.js';
const { Gtk } = imports.gi;
const Lang = imports.lang;
export const RoundedCorner = (place, props) => Widget({
...props,
type: Gtk.DrawingArea,
halign: place.includes('left') ? 'start' : 'end',
valign: place.includes('top') ? 'start' : 'end',
setup: widget => {
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
widget.set_size_request(r, r);
widget.connect('draw', Lang.bind(widget, (widget, cr) => {
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
// const borderColor = widget.get_style_context().get_property('color', Gtk.StateFlags.NORMAL);
// const borderWidth = widget.get_style_context().get_border(Gtk.StateFlags.NORMAL).left; // ur going to write border-width: something anyway
widget.set_size_request(r, r);
switch (place) {
case 'topleft':
cr.arc(r, r, r, Math.PI, 3 * Math.PI / 2);
cr.lineTo(0, 0);
break;
case 'topright':
cr.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI);
cr.lineTo(r, 0);
break;
case 'bottomleft':
cr.arc(r, 0, r, Math.PI / 2, Math.PI);
cr.lineTo(0, r);
break;
case 'bottomright':
cr.arc(0, 0, r, 0, Math.PI / 2);
cr.lineTo(r, r);
break;
}
cr.closePath();
cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
cr.fill();
// cr.setLineWidth(borderWidth);
// cr.setSourceRGBA(borderColor.red, borderColor.green, borderColor.blue, borderColor.alpha);
// cr.stroke();
}));
},
});

View File

@@ -0,0 +1,69 @@
const { Gdk, Gtk } = imports.gi;
import { App, Service, Utils, Widget } from '../../imports.js';
const { execAsync, exec } = Utils;
import { setupCursorHover, setupCursorHoverAim } from "./cursorhover.js";
import { MaterialIcon } from './materialicon.js';
export const searchItem = ({ materialIconName, name, actionName, content, onActivate }) => {
const actionText = Widget.Revealer({
revealChild: false,
transition: "crossfade",
transitionDuration: 200,
child: Widget.Label({
className: 'overview-search-results-txt txt txt-small txt-action',
label: `${actionName}`,
})
});
const actionTextRevealer = Widget.Revealer({
revealChild: false,
transition: "slide_left",
transitionDuration: 300,
child: actionText,
})
return Widget.Button({
className: 'overview-search-result-btn',
onClicked: onActivate,
child: Widget.Box({
children: [
Widget.Box({
vertical: false,
children: [
Widget.Label({
className: `icon-material overview-search-results-icon`,
label: `${materialIconName}`,
}),
Widget.Box({
vertical: true,
children: [
Widget.Label({
halign: 'start',
className: 'overview-search-results-txt txt txt-smallie txt-subtext',
label: `${name}`,
truncate: "end",
}),
Widget.Label({
halign: 'start',
className: 'overview-search-results-txt txt txt-norm',
label: `${content}`,
truncate: "end",
}),
]
}),
Widget.Box({ hexpand: true }),
actionTextRevealer,
],
})
]
}),
connections: [
['focus-in-event', (button) => {
actionText.revealChild = true;
actionTextRevealer.revealChild = true;
}],
['focus-out-event', (button) => {
actionText.revealChild = false;
actionTextRevealer.revealChild = false;
}],
]
});
}

View File

@@ -0,0 +1,9 @@
const { Gdk, Gtk } = imports.gi;
import { App, Service, Utils, Widget } from '../../imports.js';
const { execAsync, exec } = Utils;
import { setupCursorHover, setupCursorHoverAim } from "./cursorhover.js";
import { MaterialIcon } from './materialicon.js';
export const separatorLine = Widget.Box({
className: 'separator-line',
})