// 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; } }