I lived bitch
This commit is contained in:
parent
0c9c0f1b3d
commit
278186d5ef
9 changed files with 166 additions and 143 deletions
|
@ -1,5 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist gettext-domain="beekeeper">
|
||||
<schemalist>
|
||||
<schema id="xyz.trollcall.Beekeeper" path="/xyz/trollcall/Beekeeper/">
|
||||
<key name="pathname" type="s">
|
||||
<default>"/"</default>
|
||||
<summary>Current path</summary>
|
||||
<description>The current path Beekeeper looks in.</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
import Gtk from 'gi://Gtk';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import Pango from 'gi://Pango';
|
||||
|
||||
export function isSamePath(p1, p2) {
|
||||
const file1 = Gio.File.new_for_path(p1);
|
||||
const file2 = Gio.File.new_for_path(p2);
|
||||
return file1.equal(file2);
|
||||
}
|
||||
|
||||
export function getFilesInFolder(folderPath) {
|
||||
let folder = Gio.File.new_for_path(folderPath);
|
||||
while (folder && !folder.query_exists(null)) {
|
||||
folder = folder.get_parent();
|
||||
}
|
||||
if (folder === null) folder = Gio.File.new_for_path("/");
|
||||
settings.set("pathname", "s", folder.get_path());
|
||||
let files = folder.enumerate_children(
|
||||
"*",
|
||||
Gio.FileQueryInfoFlags.NONE,
|
||||
|
@ -14,11 +26,13 @@ export function getFilesInFolder(folderPath) {
|
|||
let fileNames = [];
|
||||
|
||||
while (file !== null) {
|
||||
if (file.get_file_type() === Gio.FileType.DIRECTORY)
|
||||
// if (file.get_file_type() === Gio.FileType.DIRECTORY)
|
||||
fileNames.push({
|
||||
name: file.get_name(),
|
||||
icon: file.get_icon(),
|
||||
type: file.get_content_type(),
|
||||
hidden: file.get_is_hidden(),
|
||||
path: GLib.build_filenamev([folder.get_path(), file.get_name()]),
|
||||
time:
|
||||
(file.get_modification_date_time() ??
|
||||
file.get_creation_date_time() ??
|
||||
|
@ -64,6 +78,7 @@ export function indexObjects(array) {
|
|||
ellipsize: "end",
|
||||
label: item.name,
|
||||
valign: "baseline",
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
xalign: 0.0,
|
||||
});
|
||||
|
||||
|
@ -72,7 +87,7 @@ export function indexObjects(array) {
|
|||
const path = new Gtk.Label({
|
||||
cssClasses: ["dim-label"],
|
||||
ellipsize: "end",
|
||||
label: GLib.DateTime.new_from_unix_utc(item.time).format("%x, %X"),
|
||||
label: `${GLib.DateTime.new_from_unix_utc(item.time).format("%x, %X")} | ${item.type}`,
|
||||
valign: "baseline",
|
||||
xalign: 0.0,
|
||||
});
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<interface>
|
||||
<requires lib="gtk" version="4.6"/>
|
||||
<object class="GtkWindow" id="modalWindow">
|
||||
<property name="accessible-role">note</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="title">Cum Balance</property>
|
||||
<property name="titlebar">header_bar</property>
|
||||
<child>
|
||||
<object class="GtkHeaderBar" id="header_bar">
|
||||
<property name="decoration-layout">:close</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin-bottom">16</property>
|
||||
<property name="margin-end">16</property>
|
||||
<property name="margin-start">16</property>
|
||||
<property name="margin-top">16</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">8</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">folder</property>
|
||||
<property name="icon-size">large</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="css-classes">title-2</property>
|
||||
<property name="label">Cambalache</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="margin-bottom">8</property>
|
||||
<property name="margin-top">8</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="buttonHolder">
|
||||
<property name="halign">center</property>
|
||||
<property name="spacing">8</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="css-classes">circular</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="icon-name">accessories-calculator</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
24
src/main.js
24
src/main.js
|
@ -36,25 +36,27 @@ export const BeekeeperApplication = GObject.registerClass(
|
|||
this.quit();
|
||||
});
|
||||
this.add_action(quit_action);
|
||||
this.set_accels_for_action('app.quit', ['<primary>q']);
|
||||
this.set_accels_for_action('app.quit', ['<primary>q', 'Escape']);
|
||||
|
||||
const show_about_action = new Gio.SimpleAction({name: 'about'});
|
||||
show_about_action.connect('activate', action => {
|
||||
let aboutParams = {
|
||||
authors: [
|
||||
'MeowcaTheoRange'
|
||||
],
|
||||
const aboutDialog = new Adw.AboutWindow({
|
||||
developer_name: 'MeowcaTheoRange',
|
||||
copyright: '\u00A9 2023 MeowcaTheoRange',
|
||||
version: '0.1.0',
|
||||
logo_icon_name: 'xyz.trollcall.Beekeeper',
|
||||
application_icon: 'xyz.trollcall.Beekeeper',
|
||||
license_type: Gtk.License.APACHE_2_0,
|
||||
program_name: 'Beekeeper',
|
||||
application_name: 'Beekeeper',
|
||||
transient_for: this.active_window,
|
||||
website: 'https://trollcall.xyz/',
|
||||
modal: true,
|
||||
};
|
||||
const aboutDialog = new Gtk.AboutDialog(aboutParams);
|
||||
comments: `Beekeeper is a productive project manager made for easy access to your project directories.`
|
||||
});
|
||||
aboutDialog.present();
|
||||
});
|
||||
this.add_action(show_about_action);
|
||||
|
||||
this.#loadSettings();
|
||||
}
|
||||
|
||||
vfunc_activate() {
|
||||
|
@ -65,6 +67,10 @@ export const BeekeeperApplication = GObject.registerClass(
|
|||
|
||||
active_window.present();
|
||||
}
|
||||
|
||||
#loadSettings() {
|
||||
globalThis.settings = new Gio.Settings({ schemaId: this.applicationId });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
#main-button {
|
||||
background-color: @accent_bg_color;
|
||||
color: @accent_fg_color;
|
||||
}
|
||||
|
||||
#entry-box {
|
||||
font-weight: bold;
|
||||
border-radius: 32px;
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
#entry-box:not(:focus-within) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
|
110
src/window.js
110
src/window.js
|
@ -17,44 +17,114 @@
|
|||
|
||||
import GObject from 'gi://GObject';
|
||||
import Gtk from 'gi://Gtk';
|
||||
import Gdk from 'gi://Gdk';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
|
||||
import { getFilesInFolder, indexObjects } from './folders.js';
|
||||
import { getFilesInFolder, indexObjects, isSamePath } from './folders.js';
|
||||
|
||||
export const BeekeeperWindow = GObject.registerClass({
|
||||
GTypeName: 'BeekeeperWindow',
|
||||
Template: 'resource:///xyz/trollcall/Beekeeper/window.ui',
|
||||
InternalChildren: ['label', 'folders', 'bigBox', 'userName', 'timeThingy'],
|
||||
InternalChildren: [
|
||||
'userName',
|
||||
'timeThingy',
|
||||
'holderBox',
|
||||
'entryBox',
|
||||
'emergencyProp'
|
||||
],
|
||||
}, class BeekeeperWindow extends Gtk.ApplicationWindow {
|
||||
#_folders;
|
||||
#_bigBox;
|
||||
#_userName;
|
||||
#_timeThingy;
|
||||
#_entryBox;
|
||||
#_emergencyProp;
|
||||
|
||||
#bigBox;
|
||||
#continueLabel;
|
||||
#folders;
|
||||
#earlierLabel;
|
||||
|
||||
_init(application) {
|
||||
super._init({application})
|
||||
|
||||
this._userName.set_text(`Welcome, ${GLib.get_real_name().split(" ")[0]}!`);
|
||||
this._userName.set_text(`Welcome, ${GLib.get_real_name()}!`);
|
||||
this._timeThingy.set_text(`It is ${GLib.DateTime.new_now_local().format("%X")}.`);
|
||||
setInterval(() => this._timeThingy.set_text(`It is ${GLib.DateTime.new_now_local().format("%X")}.`), 500);
|
||||
const getModal = (row) => {
|
||||
let builder = Gtk.Builder.new_from_resource("/xyz/trollcall/Beekeeper/gtk/modal.ui");
|
||||
let modalWindow = builder.get_object("modalWindow");
|
||||
modalWindow.set_modal(true);
|
||||
modalWindow.set_transient_for(this);
|
||||
print(row);
|
||||
const recommendedTypes = Gio.AppInfo.get_recommended_for_type(row.get_child().get_child_at_index(0).icon_name);
|
||||
modalWindow.present();
|
||||
|
||||
settings.bind('pathname', this._entryBox, 'text', Gio.SettingsBindFlags.BIND_SET << Gio.SettingsBindFlags.BIND_GET);
|
||||
let prev = this._entryBox.text;
|
||||
this._entryBox.connect("activate", () => {
|
||||
this.make_window(false, this._entryBox.text, prev);
|
||||
prev = this._entryBox.text;
|
||||
});
|
||||
this.make_window(true, prev);
|
||||
}
|
||||
|
||||
this._bigBox.connect("row_activated", getModal);
|
||||
this._folders.connect("row_activated", getModal);
|
||||
make_window(immune, now, prev) {
|
||||
if (!immune && isSamePath(now, prev)) return;
|
||||
if (this.bigBox) this._holderBox.remove(this.bigBox);
|
||||
if (this.continueLabel) this._holderBox.remove(this.continueLabel);
|
||||
if (this.folders) this._holderBox.remove(this.folders);
|
||||
if (this.earlierLabel) this._holderBox.remove(this.earlierLabel);
|
||||
|
||||
let folderPath = "Documents/github/";
|
||||
let files = getFilesInFolder(folderPath);
|
||||
let GtkBoxThings = indexObjects(files);
|
||||
GtkBoxThings.splice(0, 3).map(x => this._bigBox.append(x));
|
||||
GtkBoxThings.map(x => this._folders.append(x));
|
||||
const launch_shit = (row, offset) => {
|
||||
console.log(row);
|
||||
if (row.get_selected_row) row = row.get_selected_row();
|
||||
const file = files[row.get_index() + offset];
|
||||
|
||||
const filetype = Gio.AppInfo.get_default_for_type(file.type, false);
|
||||
const path = GLib.filename_to_uri(file.path, null);
|
||||
|
||||
if (filetype) filetype.launch_default_for_uri(path);
|
||||
else Gio.AppInfo.launch_default_for_uri(path, null);
|
||||
}
|
||||
|
||||
const offset = 3;
|
||||
|
||||
const folderPath = now || "";
|
||||
const files = getFilesInFolder(folderPath);
|
||||
const GtkBoxThings = indexObjects(files);
|
||||
if (GtkBoxThings.length > 0) {
|
||||
this.continueLabel = new Gtk.Label({
|
||||
label: "Continue",
|
||||
xalign: "0",
|
||||
css_classes: [
|
||||
"heading"
|
||||
]
|
||||
});
|
||||
this._holderBox.append(this.continueLabel);
|
||||
this.bigBox = new Gtk.ListBox({
|
||||
name: "main-button",
|
||||
selection_mode: "single",
|
||||
css_classes: [
|
||||
"boxed-list"
|
||||
]
|
||||
})
|
||||
this._holderBox.append(this.bigBox);
|
||||
this.bigBox.connect("row-activated", (l, r) => launch_shit(r, 0));
|
||||
GtkBoxThings.splice(0, offset).map(x => this.bigBox.append(x));
|
||||
}
|
||||
if (GtkBoxThings.length > 0) {
|
||||
this.earlierLabel = new Gtk.Label({
|
||||
label: "Earlier",
|
||||
xalign: "0",
|
||||
css_classes: [
|
||||
"heading"
|
||||
]
|
||||
});
|
||||
this._holderBox.append(this.earlierLabel);
|
||||
this.folders = new Gtk.ListBox({
|
||||
margin_start: 8,
|
||||
margin_end: 8,
|
||||
selection_mode: "single",
|
||||
css_classes: [
|
||||
"boxed-list"
|
||||
]
|
||||
})
|
||||
this._holderBox.append(this.folders);
|
||||
this.folders.connect("row-activated", (l, r) => launch_shit(r, offset));
|
||||
GtkBoxThings.map(x => this.folders.append(x));
|
||||
}
|
||||
this._emergencyProp.set_propagate_natural_height(true);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3,17 +3,31 @@
|
|||
<requires lib="gtk" version="4.0"/>
|
||||
<requires lib="libadwaita" version="1.1"/>
|
||||
<template class="BeekeeperWindow" parent="GtkApplicationWindow">
|
||||
<property name="default-height">600</property>
|
||||
<property name="default-height">0</property>
|
||||
<property name="default-width">400</property>
|
||||
<property name="title">Beekeeper</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header_bar">
|
||||
<property name="decoration-layout">:close</property>
|
||||
<child type="start">
|
||||
<object class="GtkMenuButton">
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
<property name="menu-model">primary_menu</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<property name="title-widget">
|
||||
<object class="GtkEntry" id="entryBox">
|
||||
<property name="name">entry-box</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="width-chars">20</property>
|
||||
<property name="placeholder-text">/home/...</property>
|
||||
</object>
|
||||
</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
|
@ -23,9 +37,10 @@
|
|||
<object class="GtkBox" id="label">
|
||||
<property name="orientation">1</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<object class="GtkScrolledWindow" id="emergencyProp">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="min-content-height">400</property>
|
||||
<property name="propagate-natural-height">1</property>
|
||||
<property name="max-content-height">600</property>
|
||||
<property name="min-content-width">400</property>
|
||||
<child>
|
||||
<object class="AdwClamp" id="child">
|
||||
|
@ -35,10 +50,11 @@
|
|||
<property name="tightening-threshold">400</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkBox" id="holderBox">
|
||||
<property name="margin-bottom">16</property>
|
||||
<property name="margin-top">8</property>
|
||||
<property name="orientation">1</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="spacing">8</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="userName">
|
||||
|
@ -58,43 +74,6 @@
|
|||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Continue</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="bigBox">
|
||||
<property name="name">main-button</property>
|
||||
<property name="selection-mode">browse</property>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Earlier</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="folders">
|
||||
<property name="margin-end">8</property>
|
||||
<property name="margin-start">8</property>
|
||||
<property name="selection-mode">browse</property>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -107,10 +86,6 @@
|
|||
|
||||
<menu id="primary_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Preferences</attribute>
|
||||
<attribute name="action">app.preferences</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
|
||||
<attribute name="action">win.show-help-overlay</attribute>
|
||||
|
|
|
@ -4,6 +4,5 @@
|
|||
<file>style.css</file>
|
||||
<file>window.ui</file>
|
||||
<file>gtk/help-overlay.ui</file>
|
||||
<file>gtk/modal.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"app-id" : "xyz.trollcall.Beekeeper",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "master",
|
||||
"runtime-version" : "44",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "xyz.trollcall.Beekeeper",
|
||||
"finish-args" : [
|
||||
|
@ -30,9 +30,12 @@
|
|||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "file:///home/theorange/Projects/Beekeeper"
|
||||
"url" : "file:///home/mtr/Projects/Builder/projects/Beekeeper"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : { }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue