Compare commits
3
Commits
main
..
honney/tray
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02606e5ab3 | ||
|
|
c7b0ed957a | ||
|
|
c011c76900 |
@@ -1,5 +1 @@
|
|||||||
*.svg
|
|
||||||
Colors.qml
|
Colors.qml
|
||||||
modules/wlogout/scripts/helper.sh
|
|
||||||
config/path/ConfigPath.qml
|
|
||||||
config/path/WallpaperPath.qml
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# HyprlandQuickshellGUI: a replacement for Waybar
|
|
||||||
|
|
||||||
Run install.sh to make the quickshell runable
|
|
||||||
|
|
||||||
## Colors
|
|
||||||
### [Matugen](https://github.com/InioX/matugen)
|
|
||||||
We use [matugen](https://github.com/InioX/matugen) for the colors. With these Templates for Some Applications we use: [maguten-config](https://git.honney333.work/honney/matugen-config)
|
|
||||||
|
|
||||||
## Wallpaper
|
|
||||||
We use a custom directory by deafault to save all your Wallpapers:
|
|
||||||
```
|
|
||||||
$HOME/Pictures/Wallpapers/
|
|
||||||
```
|
|
||||||
### Compatible Wallpaper Software:
|
|
||||||
- [hyprpaper](https://github.com/hyprwm/hyprpaper)
|
|
||||||
- [swww](https://github.com/LGFae/swww)
|
|
||||||
- [awww (comming)](https://codeberg.org/LGFae/awww)
|
|
||||||
|
|
||||||
### Recommended Software for some stuff:
|
|
||||||
- [ImageMagick (resizing & blurring)](https://github.com/ImageMagick/ImageMagick)
|
|
||||||
|
|
||||||
## Other Software:
|
|
||||||
### Logout:
|
|
||||||
- [wlogout](https://github.com/ArtsyMacaw/wlogout)
|
|
||||||
- [nmcli (Recommended for Wifi)](https://github.com/ushiboy/nmcli)
|
|
||||||
|
|
||||||
## TO Enable Sub Programs:
|
|
||||||
Add the Lines to your ```~/.config/hypr/hyprland.conf``` keep in mind that you might need to change the Keybind.
|
|
||||||
### Wallpaper Picker
|
|
||||||
```bind = $mainMod SHIFT, W, global, quickshell:Wallpaper```
|
|
||||||
### JLearner
|
|
||||||
```bind = $mainMod SHIFT, J, global, quickshell:JLearner```
|
|
||||||
|
|
||||||
# TODO:
|
|
||||||
|
|
||||||
- Volume Contol
|
|
||||||
- Notes
|
|
||||||
- wofi
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 MiB |
@@ -1,57 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick 2.15
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
|
|
||||||
// ===== PRIMARY =====
|
|
||||||
readonly property color primary: "#cbcb77"
|
|
||||||
readonly property color primary_fg: "#323200"
|
|
||||||
readonly property color primaryContainer: "#494900"
|
|
||||||
readonly property color primaryContainer_fg: "#e7e790"
|
|
||||||
|
|
||||||
// ===== SECONDARY =====
|
|
||||||
readonly property color secondary: "#cac8a5"
|
|
||||||
readonly property color secondary_fg: "#323218"
|
|
||||||
readonly property color secondaryContainer: "#48482d"
|
|
||||||
readonly property color secondaryContainer_fg: "#e6e4bf"
|
|
||||||
|
|
||||||
// ===== TERTIARY =====
|
|
||||||
readonly property color tertiary: "#a4d0bd"
|
|
||||||
readonly property color tertiary_fg: "#0a372a"
|
|
||||||
readonly property color tertiaryContainer: "#254e40"
|
|
||||||
readonly property color tertiaryContainer_fg: "#bfecd9"
|
|
||||||
|
|
||||||
// ===== ERROR =====
|
|
||||||
readonly property color error: "#ffb4ab"
|
|
||||||
readonly property color error_fg: "#690005"
|
|
||||||
readonly property color errorContainer: "#93000a"
|
|
||||||
readonly property color errorContainer_fg: "#ffdad6"
|
|
||||||
|
|
||||||
// ===== BACKGROUND / SURFACE =====
|
|
||||||
readonly property color background: "#14140c"
|
|
||||||
readonly property color background_fg: "#e6e3d5"
|
|
||||||
|
|
||||||
readonly property color surface: "#14140c"
|
|
||||||
readonly property color surface_fg: "#e6e3d5"
|
|
||||||
|
|
||||||
readonly property color surfaceVariant: "#48473a"
|
|
||||||
readonly property color surfaceVariant_fg: "#c9c7b6"
|
|
||||||
|
|
||||||
// ===== SURFACE CONTAINERS =====
|
|
||||||
readonly property color surfaceContainerLowest: "#0f0f07"
|
|
||||||
readonly property color surfaceContainerLow: "#1c1c14"
|
|
||||||
readonly property color surfaceContainer: "#202018"
|
|
||||||
readonly property color surfaceContainerHigh: "#2b2a22"
|
|
||||||
readonly property color surfaceContainerHighest: "#36352c"
|
|
||||||
|
|
||||||
// ===== OUTLINE / UTILITY =====
|
|
||||||
readonly property color outline: "#939182"
|
|
||||||
readonly property color outlineVariant: "#48473a"
|
|
||||||
readonly property color shadowColor: "#000000"
|
|
||||||
readonly property color scrimColor: "#000000"
|
|
||||||
|
|
||||||
// ===== INVERSE =====
|
|
||||||
readonly property color inverseSurface: "#e6e3d5"
|
|
||||||
readonly property color inverseSurface_fg: "#313128"
|
|
||||||
readonly property color inversePrimary: "#616219"
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick 2.15
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
|
|
||||||
// ===== PRIMARY =====
|
|
||||||
readonly property color primary: "#cbcb77"
|
|
||||||
readonly property color primary_fg: "#323200"
|
|
||||||
readonly property color primaryContainer: "#494900"
|
|
||||||
readonly property color primaryContainer_fg: "#e7e790"
|
|
||||||
|
|
||||||
// ===== SECONDARY =====
|
|
||||||
readonly property color secondary: "#cac8a5"
|
|
||||||
readonly property color secondary_fg: "#323218"
|
|
||||||
readonly property color secondaryContainer: "#48482d"
|
|
||||||
readonly property color secondaryContainer_fg: "#e6e4bf"
|
|
||||||
|
|
||||||
// ===== TERTIARY =====
|
|
||||||
readonly property color tertiary: "#a4d0bd"
|
|
||||||
readonly property color tertiary_fg: "#0a372a"
|
|
||||||
readonly property color tertiaryContainer: "#254e40"
|
|
||||||
readonly property color tertiaryContainer_fg: "#bfecd9"
|
|
||||||
|
|
||||||
// ===== ERROR =====
|
|
||||||
readonly property color error: "#ffb4ab"
|
|
||||||
readonly property color error_fg: "#690005"
|
|
||||||
readonly property color errorContainer: "#93000a"
|
|
||||||
readonly property color errorContainer_fg: "#ffdad6"
|
|
||||||
|
|
||||||
// ===== BACKGROUND / SURFACE =====
|
|
||||||
readonly property color background: "#14140c"
|
|
||||||
readonly property color background_fg: "#e6e3d5"
|
|
||||||
|
|
||||||
readonly property color surface: "#14140c"
|
|
||||||
readonly property color surface_fg: "#e6e3d5"
|
|
||||||
|
|
||||||
readonly property color surfaceVariant: "#48473a"
|
|
||||||
readonly property color surfaceVariant_fg: "#c9c7b6"
|
|
||||||
|
|
||||||
// ===== SURFACE CONTAINERS =====
|
|
||||||
readonly property color surfaceContainerLowest: "#0f0f07"
|
|
||||||
readonly property color surfaceContainerLow: "#1c1c14"
|
|
||||||
readonly property color surfaceContainer: "#202018"
|
|
||||||
readonly property color surfaceContainerHigh: "#2b2a22"
|
|
||||||
readonly property color surfaceContainerHighest: "#36352c"
|
|
||||||
|
|
||||||
// ===== OUTLINE / UTILITY =====
|
|
||||||
readonly property color outline: "#939182"
|
|
||||||
readonly property color outlineVariant: "#48473a"
|
|
||||||
readonly property color shadowColor: "#000000"
|
|
||||||
readonly property color scrimColor: "#000000"
|
|
||||||
|
|
||||||
// ===== INVERSE =====
|
|
||||||
readonly property color inverseSurface: "#e6e3d5"
|
|
||||||
readonly property color inverseSurface_fg: "#313128"
|
|
||||||
readonly property color inversePrimary: "#616219"
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick 2.15
|
|
||||||
import "./path"
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
readonly property string configDir: ConfigPath.path
|
|
||||||
readonly property string wallpaperDir: WallpaperPath.wallpaperDir
|
|
||||||
|
|
||||||
readonly property int small_spacing: 4
|
|
||||||
readonly property int spacing: 8
|
|
||||||
function small_spacing_fun(screenHeight) { return Math.floor(barHeight(screenHeight) / 16) }
|
|
||||||
function spacing_fun(barH) { return Math.floor(barH / 8) }
|
|
||||||
function big_spacing_fun(barH) { return Math.floor(barH / 6) }
|
|
||||||
|
|
||||||
function font_size(spaceHeight) { return Math.floor(spaceHeight * 0.75) }
|
|
||||||
function font_size_small(spaceHeight) { return Math.floor(spaceHeight * 0.625) }
|
|
||||||
function font_size_tiny(spaceHeight) { return Math.floor(spaceHeight * 0.4) }
|
|
||||||
|
|
||||||
readonly property int small_radius: 8
|
|
||||||
readonly property int radius: 16
|
|
||||||
function small_radius_fun(barHeight) { return Math.floor(barHeight / 8) }
|
|
||||||
function radius_fun(barHeight) { return Math.floor(barHeight / 4) }
|
|
||||||
readonly property int big_radius: 10
|
|
||||||
readonly property int border_width: 2
|
|
||||||
|
|
||||||
readonly property string font: "CodeNewRoman Nerd Font"
|
|
||||||
|
|
||||||
function big_font_size(value) {
|
|
||||||
return value * 0.6
|
|
||||||
}
|
|
||||||
|
|
||||||
function medium_scaling(value) {
|
|
||||||
return value * 0.4
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale font/icon size relative to bar height
|
|
||||||
function bigIconSize(barHeight) { return Math.floor(barHeight * 0.7) }
|
|
||||||
function halfBigIconSize(barHeight) { return Math.floor(barHeight * 0.6) }
|
|
||||||
function iconSize(barHeight) { return Math.floor(barHeight * 0.5) }
|
|
||||||
function labelSize(barHeight) { return Math.floor(barHeight * 0.35) }
|
|
||||||
function normalSpacing(screenHeight) { return Math.floor(barHeight(screenHeight) / 4) }
|
|
||||||
function widgetSpacing(screenHeight) { return Math.floor(barHeight(screenHeight) / 8) }
|
|
||||||
|
|
||||||
function barHeight(screenHeight) {
|
|
||||||
return Math.floor(screenHeight * barHeightRatio(screenHeight))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolution-aware bar height ratio
|
|
||||||
function barHeightRatio(screenHeight) {
|
|
||||||
return screenHeight >= 2160 ? 0.03 :
|
|
||||||
screenHeight >= 1440 ? 0.035 :
|
|
||||||
0.04
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tray
|
|
||||||
readonly property int reload_interval: 10000
|
|
||||||
readonly property int fast_reload_interval: 1000
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function maxTextWidth(maxNum, texts) {
|
|
||||||
let maxWidth = 0;
|
|
||||||
|
|
||||||
for (let i = 0; i < Math.min(maxNum, texts.length); i++)
|
|
||||||
maxWidth = Math.max(maxWidth, texts[i].width);
|
|
||||||
|
|
||||||
return maxWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick 2.15
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
readonly property string path: "__CONFIG_DIR__"
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
property string wallpaperDir: "__CONFIG_DIR__"
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
singleton ConfigPath ConfigPath.qml
|
|
||||||
singleton WallpaperPath WallpaperPath.qml
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
singleton Config Config.qml
|
|
||||||
singleton Colors Colors.qml
|
|
||||||
-183
@@ -1,183 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
|
||||||
|
|
||||||
cp "$SCRIPT_DIR/config/Colors.qml.template" "$SCRIPT_DIR/config/Colors.qml"
|
|
||||||
|
|
||||||
cp "$SCRIPT_DIR/config/path/ConfigPath.qml.template" "$SCRIPT_DIR/config/path/ConfigPath.qml"
|
|
||||||
sed -i "s|__CONFIG_DIR__|$SCRIPT_DIR|g" "$SCRIPT_DIR/config/path/ConfigPath.qml"
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# UI helpers
|
|
||||||
# ----------------------------
|
|
||||||
info() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
|
|
||||||
ok() { echo -e "\033[1;32m[ OK ]\033[0m $*"; }
|
|
||||||
warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; }
|
|
||||||
fail() { echo -e "\033[1;31m[FAIL]\033[0m $*"; }
|
|
||||||
|
|
||||||
download() {
|
|
||||||
local url="$1"
|
|
||||||
local out="$2"
|
|
||||||
local name="${3:-$(basename "$out")}"
|
|
||||||
|
|
||||||
info "Downloading $name"
|
|
||||||
|
|
||||||
if curl -fL --progress-bar "$url" -o "$out"; then
|
|
||||||
ok "Saved $name"
|
|
||||||
else
|
|
||||||
fail "Failed $name"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
transform_svg_white() {
|
|
||||||
local url="$1"
|
|
||||||
local out="$2"
|
|
||||||
local name="${3:-$(basename "$out")}"
|
|
||||||
|
|
||||||
info "Fetching + whitening $name"
|
|
||||||
|
|
||||||
if curl -fsSL "$url" \
|
|
||||||
| sed -E 's/#[0-9a-fA-F]{3,6}/#ffffff/g' \
|
|
||||||
> "$out"; then
|
|
||||||
ok "Generated $name"
|
|
||||||
else
|
|
||||||
fail "Failed $name"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# Start
|
|
||||||
# ----------------------------
|
|
||||||
echo
|
|
||||||
info "Preparing wlogout icons..."
|
|
||||||
mkdir -p "$SCRIPT_DIR/modules/wlogout/icons"
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# Icons (wlogout)
|
|
||||||
# ----------------------------
|
|
||||||
transform_svg_white \
|
|
||||||
"https://raw.githubusercontent.com/vinceliuice/Colloid-icon-theme/main/src/actions/symbolic/system-hibernate-symbolic.svg" \
|
|
||||||
"$SCRIPT_DIR/modules/wlogout/icons/hibernate.svg" \
|
|
||||||
"hibernate.svg"
|
|
||||||
|
|
||||||
transform_svg_white \
|
|
||||||
"https://raw.githubusercontent.com/vinceliuice/Colloid-icon-theme/main/bold/actions/symbolic/system-lock-screen-symbolic.svg" \
|
|
||||||
"$SCRIPT_DIR/modules/wlogout/icons/lock.svg" \
|
|
||||||
"lock.svg"
|
|
||||||
|
|
||||||
transform_svg_white \
|
|
||||||
"https://raw.githubusercontent.com/vinceliuice/Colloid-icon-theme/main/src/status/symbolic/logout-symbolic.svg" \
|
|
||||||
"$SCRIPT_DIR/modules/wlogout/icons/logout.svg" \
|
|
||||||
"logout.svg"
|
|
||||||
|
|
||||||
transform_svg_white \
|
|
||||||
"https://raw.githubusercontent.com/vinceliuice/Colloid-icon-theme/main/src/actions/symbolic/system-reboot-symbolic.svg" \
|
|
||||||
"$SCRIPT_DIR/modules/wlogout/icons/reboot.svg" \
|
|
||||||
"reboot.svg"
|
|
||||||
|
|
||||||
transform_svg_white \
|
|
||||||
"https://raw.githubusercontent.com/vinceliuice/Colloid-icon-theme/main/src/actions/symbolic/system-shutdown-symbolic.svg" \
|
|
||||||
"$SCRIPT_DIR/modules/wlogout/icons/shutdown.svg" \
|
|
||||||
"shutdown.svg"
|
|
||||||
|
|
||||||
transform_svg_white \
|
|
||||||
"https://raw.githubusercontent.com/vinceliuice/Colloid-icon-theme/main/src/actions/24/system-suspend.svg" \
|
|
||||||
"$SCRIPT_DIR/modules/wlogout/icons/suspend.svg" \
|
|
||||||
"suspend.svg"
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# UI icons
|
|
||||||
# ----------------------------
|
|
||||||
echo
|
|
||||||
info "Preparing global icons..."
|
|
||||||
mkdir -p "$SCRIPT_DIR/modules/jl/assets"
|
|
||||||
|
|
||||||
download \
|
|
||||||
"https://raw.githubusercontent.com/Tekh-ops/Garuda-Linux-Icons/refs/heads/master/actions/scalable/window-close.svg" \
|
|
||||||
"$SCRIPT_DIR/modules/jl/assets/wrong.svg" \
|
|
||||||
"wrong.svg"
|
|
||||||
|
|
||||||
download \
|
|
||||||
"https://raw.githubusercontent.com/Tekh-ops/Garuda-Linux-Icons/refs/heads/master/actions/scalable/dialog-ok-apply.svg" \
|
|
||||||
"$SCRIPT_DIR/modules/jl/assets/correct.svg" \
|
|
||||||
"correct.svg"
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# Nerd Font
|
|
||||||
# ----------------------------
|
|
||||||
echo
|
|
||||||
info "Installing CodeNewRoman Nerd Font..."
|
|
||||||
FONT_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/fonts"
|
|
||||||
mkdir -p "$FONT_DIR"
|
|
||||||
|
|
||||||
if [ ! -f "$FONT_DIR/CodeNewRomanNerdFont-Regular.ttf" ]; then
|
|
||||||
download \
|
|
||||||
"https://github.com/ryanoasis/nerd-fonts/releases/latest/download/CodeNewRoman.tar.xz" \
|
|
||||||
"/tmp/CodeNewRoman.tar.xz" \
|
|
||||||
"CodeNewRoman Nerd Font"
|
|
||||||
|
|
||||||
tar -xf /tmp/CodeNewRoman.tar.xz -C "$FONT_DIR" --wildcards '*.ttf' 2>/dev/null || \
|
|
||||||
tar -xf /tmp/CodeNewRoman.tar.xz -C "$FONT_DIR"
|
|
||||||
rm -f /tmp/CodeNewRoman.tar.xz
|
|
||||||
|
|
||||||
if command -v fc-cache &>/dev/null; then
|
|
||||||
fc-cache -fv "$FONT_DIR" &>/dev/null
|
|
||||||
fi
|
|
||||||
ok "CodeNewRoman Nerd Font installed"
|
|
||||||
else
|
|
||||||
ok "CodeNewRoman Nerd Font already installed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# Japanese Font (for JLearner)
|
|
||||||
# ----------------------------
|
|
||||||
echo
|
|
||||||
info "Installing Noto Sans JP font..."
|
|
||||||
|
|
||||||
if [ ! -f "$FONT_DIR/NotoSansJP.ttf" ]; then
|
|
||||||
download \
|
|
||||||
"https://github.com/google/fonts/raw/main/ofl/notosansjp/NotoSansJP%5Bwght%5D.ttf" \
|
|
||||||
"$FONT_DIR/NotoSansJP.ttf" \
|
|
||||||
"Noto Sans JP"
|
|
||||||
|
|
||||||
ok "Noto Sans JP font installed"
|
|
||||||
else
|
|
||||||
ok "Noto Sans JP font already installed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# Font cache reload
|
|
||||||
# ----------------------------
|
|
||||||
echo
|
|
||||||
info "Reloading font cache..."
|
|
||||||
if command -v fc-cache &>/dev/null; then
|
|
||||||
fc-cache -fv &>/dev/null
|
|
||||||
ok "Font cache reloaded"
|
|
||||||
else
|
|
||||||
warn "fc-cache not found — font cache not updated"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# Example Wallpaper
|
|
||||||
# ----------------------------
|
|
||||||
echo
|
|
||||||
info "Preparing wallpaper..."
|
|
||||||
|
|
||||||
WALLPAPER_DIR=$(scripts/wallpaper_dir.sh)
|
|
||||||
|
|
||||||
mkdir -p "$WALLPAPER_DIR"
|
|
||||||
|
|
||||||
info "Copying example Wallpaper..."
|
|
||||||
|
|
||||||
cp "$SCRIPT_DIR/assets/example_background.png" "$WALLPAPER_DIR/japan_old_emperor_stream_with_bridge.png"
|
|
||||||
|
|
||||||
info "Creating Wallpaper Folder Config"
|
|
||||||
|
|
||||||
cp "$SCRIPT_DIR/config/path/WallpaperPath.qml.template" "$SCRIPT_DIR/config/path/WallpaperPath.qml"
|
|
||||||
sed -i "s|__CONFIG_DIR__|$WALLPAPER_DIR|g" "$SCRIPT_DIR/config/path/WallpaperPath.qml"
|
|
||||||
|
|
||||||
echo
|
|
||||||
ok "All assets prepared successfully."
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Wayland
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
// Automatically generates a trap for every connected monitor
|
|
||||||
model: Quickshell.screens
|
|
||||||
|
|
||||||
delegate: PanelWindow {
|
|
||||||
screen: modelData
|
|
||||||
|
|
||||||
// Force the panel window to take up the full screen real estate
|
|
||||||
anchors.top: true
|
|
||||||
anchors.bottom: true
|
|
||||||
anchors.left: true
|
|
||||||
anchors.right: true
|
|
||||||
|
|
||||||
// Push it to the background layer below normal windows
|
|
||||||
WlrLayershell.layer: WlrLayer.Background
|
|
||||||
WlrLayershell.namespace: "transparent-focus-trap"
|
|
||||||
|
|
||||||
// Keep it transparent so your current wallpaper shows right through
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
// The core trap mechanism
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
// Having an active hover area on the background layer forces the
|
|
||||||
// Wayland compositor to shift cursor target focus to this surface
|
|
||||||
// the exact millisecond your mouse exits a tiled/floating window.
|
|
||||||
onEntered: {
|
|
||||||
console.log("DEBUG: Mouse entered background (Focus Trap Active)");
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: {
|
|
||||||
console.log("DEBUG: Mouse left background (Focusing on Window)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+17
-11
@@ -2,7 +2,9 @@ import QtQuick
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import "./widgets"
|
import "./widgets"
|
||||||
import "../../config"
|
import "../../colors"
|
||||||
|
|
||||||
|
// TODO: interact with PyWal
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: panel
|
id: panel
|
||||||
@@ -13,7 +15,7 @@ PanelWindow {
|
|||||||
anchors.left: true
|
anchors.left: true
|
||||||
anchors.right: true
|
anchors.right: true
|
||||||
|
|
||||||
implicitHeight: Math.floor(screen.height * Config.barHeightRatio(screen.height))
|
implicitHeight: 40
|
||||||
|
|
||||||
exclusiveZone: height // this is so context menus don't clip into the bar
|
exclusiveZone: height // this is so context menus don't clip into the bar
|
||||||
|
|
||||||
@@ -29,33 +31,36 @@ PanelWindow {
|
|||||||
id: bar
|
id: bar
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Qt.alpha(Colors.background, 0.5)
|
color: Qt.alpha(Colors.background, 0.5)
|
||||||
|
radius: 0
|
||||||
|
|
||||||
Row { // bar widgets left
|
Row { // bar widgets left
|
||||||
id: widgetsLeft
|
id: widgetsLeft
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: Config.big_spacing_fun(height)
|
anchors.leftMargin: 16
|
||||||
spacing: Config.big_spacing_fun(height)
|
spacing: 8
|
||||||
|
|
||||||
MenuButton {}
|
MenuButton {}
|
||||||
|
// TODO: Add functionallity (Maybe just rofi or own way)
|
||||||
|
|
||||||
Workspaces {
|
Workspaces {
|
||||||
thisMonitor: barThisMonitor
|
thisMonitor: barThisMonitor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
// TODO: Maybe add current Apps in workspace
|
||||||
WindowInfo {}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row { // bar widgets center
|
Row { // bar widgets center
|
||||||
id: widgetsCenter
|
id: widgetsCenter
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Config.big_spacing_fun(height)
|
|
||||||
|
|
||||||
Clock {}
|
Clock {}
|
||||||
|
|
||||||
|
// TODO: Add a way to see Date (maybe hover or click)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row { // bar widgets right
|
Row { // bar widgets right
|
||||||
@@ -63,16 +68,17 @@ PanelWindow {
|
|||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 0
|
anchors.rightMargin: 16
|
||||||
spacing: Config.big_spacing_fun(height)
|
spacing: 8
|
||||||
|
|
||||||
// TODO: Add bluetooth, network, audio, power, maybe HW monitor
|
// TODO: Add bluetooth, network, audio, power, maybe HW monitor
|
||||||
Tray{}
|
Tray{}
|
||||||
Battery{}
|
|
||||||
Network {}
|
Network {}
|
||||||
IdleButton {}
|
|
||||||
PowerButton {}
|
PowerButton {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Somewhere add Tray
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Quickshell
|
|||||||
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: bar_root
|
id: root
|
||||||
Repeater { // Bars
|
Repeater { // Bars
|
||||||
model: Quickshell.screens
|
model: Quickshell.screens
|
||||||
delegate: Loader {
|
delegate: Loader {
|
||||||
|
|||||||
@@ -1,198 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
ID="$1"
|
|
||||||
|
|
||||||
if [[ -z "$ID" ]]; then
|
|
||||||
echo "Usage: $0 Number"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =========================
|
|
||||||
# ICON MAP (ADD YOUR TABLE HERE)
|
|
||||||
# =========================
|
|
||||||
# Command Helper: hyprctl clients -j | jq '.[] | select(.workspace.id == 1)'
|
|
||||||
# Icons: https://www.nerdfonts.com/cheat-sheet
|
|
||||||
declare -A MAP=(
|
|
||||||
# Youtube
|
|
||||||
["Grayjay"]=""
|
|
||||||
# Browser
|
|
||||||
["Ablaze Floorp"]=""
|
|
||||||
["floorp"]=""
|
|
||||||
["LibreWolf"]=""
|
|
||||||
["midori"]=""
|
|
||||||
["brave-browser"]=""
|
|
||||||
["chromium"]=""
|
|
||||||
# E-Mail
|
|
||||||
["org.mozilla.Thunderbird"]=""
|
|
||||||
# Terminals
|
|
||||||
["kitty"]=""
|
|
||||||
["Alacritty"]=""
|
|
||||||
# Videoplayer
|
|
||||||
["VLC media player"]=""
|
|
||||||
["mpv"]=""
|
|
||||||
["ffplay"]=""
|
|
||||||
# Video editing
|
|
||||||
["org.kde.kdenlive"]=""
|
|
||||||
# Chats
|
|
||||||
["discord"]=""
|
|
||||||
["vesktop"]=""
|
|
||||||
["Signal"]=""
|
|
||||||
["xyz.chatboxapp.app"]=""
|
|
||||||
# Coding
|
|
||||||
["Visual Studio Code"]=""
|
|
||||||
["VSCodium"]=""
|
|
||||||
["jetbrains-idea"]=""
|
|
||||||
["jetbrains-studio"]=""
|
|
||||||
# Text Editor
|
|
||||||
["org.xfce.mousepad"]=""
|
|
||||||
# Password
|
|
||||||
["org.keepassxc.KeePassXC"]=""
|
|
||||||
["Yubico Authenticator"]=""
|
|
||||||
# Cloud
|
|
||||||
["com.nextcloud.desktopclient.nextcloud"]=""
|
|
||||||
# App Store
|
|
||||||
["Octopi"]=""
|
|
||||||
# Games
|
|
||||||
["steam*"]=""
|
|
||||||
["org.prismlauncher.PrismLauncher"]=""
|
|
||||||
["Minecraft*"]=""
|
|
||||||
["game"]=""
|
|
||||||
# Digital Arts
|
|
||||||
["Blender"]=""
|
|
||||||
["Krita"]=""
|
|
||||||
# VM
|
|
||||||
["virt-manager"]=""
|
|
||||||
["VirtualBox Manager"]=""
|
|
||||||
["VirtualBox Machine"]=""
|
|
||||||
["remote-viewer"]=""
|
|
||||||
# Audio
|
|
||||||
["qpwgraph"]=""
|
|
||||||
["Carla"]=""
|
|
||||||
# Video
|
|
||||||
["com.obsproject.Studio"]=""
|
|
||||||
["hyprland-share-picker"]=""
|
|
||||||
# Document Editor/Viewer
|
|
||||||
["libreoffice-startcenter"]=""
|
|
||||||
["libreoffice-base"]=""
|
|
||||||
["libreoffice-calc"]=""
|
|
||||||
["libreoffice-draw"]=""
|
|
||||||
["libreoffice-impress"]=""
|
|
||||||
["libreoffice-math"]=""
|
|
||||||
["libreoffice-writer"]=""
|
|
||||||
["com.github.flxzt.rnote"]=""
|
|
||||||
["Xreader"]=""
|
|
||||||
["com.github.xournalpp.xournalpp"]=""
|
|
||||||
["qpdfview.local.qpdfview"]=""
|
|
||||||
# Hardware
|
|
||||||
["Mission Center"]=""
|
|
||||||
["QDirStat"]=""
|
|
||||||
["Disks"]=""
|
|
||||||
# File Manager
|
|
||||||
["nemo"]=""
|
|
||||||
["org.gnome.Nautilus"]=""
|
|
||||||
["org.kde.dolphin"]=""
|
|
||||||
["xdg-desktop-portal-gtk"]=""
|
|
||||||
# Settings
|
|
||||||
["nwg-look"]="" # gtk-settings
|
|
||||||
["qt5ct"]=""
|
|
||||||
["qt6ct"]=""
|
|
||||||
["sddm-conf"]=""
|
|
||||||
["blueman-manager"]=""
|
|
||||||
["nm-connection-editor"]=""
|
|
||||||
# Calculator
|
|
||||||
["Calculator"]=""
|
|
||||||
# VPN
|
|
||||||
["Proton VPN"]=""
|
|
||||||
["com.cisco.secureclient.gui"]=""
|
|
||||||
# Torrent
|
|
||||||
["org.qbittorrent.qBittorrent"]=""
|
|
||||||
# Hardware Design
|
|
||||||
["Xilinx Unified 2022.2 Installer"]=""
|
|
||||||
["Xilinx Information Center"]=""
|
|
||||||
["Xilinx Unified 2022.2 Installer"]=""
|
|
||||||
["vsim"]=""
|
|
||||||
# BoxBuddy
|
|
||||||
["io.github.dvlv.boxbuddyrs"]=""
|
|
||||||
# Stream
|
|
||||||
["Fladder"]=""
|
|
||||||
["crunchyroll"]=""
|
|
||||||
["netflix"]=""
|
|
||||||
["primevideo"]=""
|
|
||||||
# Image Viewer
|
|
||||||
["viewnior"]=""
|
|
||||||
# Image Editor
|
|
||||||
["gimp"]=""
|
|
||||||
["org.inkscape.Inkscape"]=""
|
|
||||||
# CNC
|
|
||||||
["LightBurn"]=""
|
|
||||||
)
|
|
||||||
|
|
||||||
# =========================
|
|
||||||
# COLLECT HYPRLAND CLIENTS
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
to_lower() {
|
|
||||||
echo "${1,,}"
|
|
||||||
}
|
|
||||||
|
|
||||||
match_map() {
|
|
||||||
local input
|
|
||||||
input="$(to_lower "$1")"
|
|
||||||
|
|
||||||
for key in "${!MAP[@]}"; do
|
|
||||||
local pattern
|
|
||||||
pattern="$(to_lower "$key")"
|
|
||||||
|
|
||||||
# wildcard + glob match
|
|
||||||
if [[ "$input" == $pattern ]]; then
|
|
||||||
echo "${MAP[$key]}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# APPS=$(hyprctl clients -j | jq -r ".[] | select(.workspace.id == $ID) | .initialTitle")
|
|
||||||
|
|
||||||
# =========================
|
|
||||||
# COLLECT HYPRLAND CLIENTS
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
mapfile -t APPS < <(
|
|
||||||
hyprctl clients -j |
|
|
||||||
jq -r ".[] | select(.workspace.id == $ID) | .initialTitle"
|
|
||||||
)
|
|
||||||
|
|
||||||
mapfile -t APPS_CLASS < <(
|
|
||||||
hyprctl clients -j |
|
|
||||||
jq -r ".[] | select(.workspace.id == $ID) | .initialClass"
|
|
||||||
)
|
|
||||||
|
|
||||||
# =========================
|
|
||||||
# MAP ICONS
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
for i in "${!APPS[@]}"; do
|
|
||||||
icon=""
|
|
||||||
|
|
||||||
icon="$(match_map "${APPS[$i]}")"
|
|
||||||
|
|
||||||
if [[ -z "$icon" ]]; then
|
|
||||||
icon="$(match_map "${APPS_CLASS[$i]}")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$icon" ]]; then
|
|
||||||
APPS[$i]="$icon"
|
|
||||||
else
|
|
||||||
APPS[$i]="${APPS_CLASS[$i]}|${APPS[$i]}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# =========================
|
|
||||||
# OUTPUT
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
RESULT="$(printf '%s' "${APPS[@]}")"
|
|
||||||
# RESULT=${RESULT% } # remove trailing space
|
|
||||||
echo "$RESULT"
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
if [ "$1" = "--status" ]; then
|
|
||||||
if pgrep -x "hypridle" >/dev/null; then
|
|
||||||
echo 1
|
|
||||||
else
|
|
||||||
echo 0
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if pgrep -x "hypridle" >/dev/null; then
|
|
||||||
killall hypridle
|
|
||||||
else
|
|
||||||
hypridle &
|
|
||||||
fi
|
|
||||||
@@ -21,7 +21,7 @@ if printf "%s\n" "${ITYPES[@]}" | grep -qx "Ethernet"; then
|
|||||||
echo " "
|
echo " "
|
||||||
elif printf "%s\n" "${ITYPES[@]}" | grep -qx "Wi-Fi"; then
|
elif printf "%s\n" "${ITYPES[@]}" | grep -qx "Wi-Fi"; then
|
||||||
if [ -x "/usr/bin/nmcli" ]; then
|
if [ -x "/usr/bin/nmcli" ]; then
|
||||||
CONNECTION="$(nmcli -f DEVICE,ACTIVE,SSID,SIGNAL dev wifi | grep yes | awk '{print $NF}')"
|
CONNECTION="$(nmcli -f DEVICE,ACTIVE,SSID,SIGNAL dev wifi | grep yes | awk '{print $4}')"
|
||||||
if [[ -z "$CONNECTION" ]]; then
|
if [[ -z "$CONNECTION" ]]; then
|
||||||
echo " "
|
echo " "
|
||||||
elif (( CONNECTION > 80 )); then
|
elif (( CONNECTION > 80 )); then
|
||||||
|
|||||||
@@ -1,188 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
// Per-workspace icon cache: maps workspaceId -> array of icon strings
|
|
||||||
property var workspaceIcons: ({})
|
|
||||||
|
|
||||||
function iconsForWorkspace(workspaceId) {
|
|
||||||
return root.workspaceIcons[workspaceId] || []
|
|
||||||
}
|
|
||||||
|
|
||||||
function matchIcon(name) {
|
|
||||||
if (!name) return ""
|
|
||||||
var lower = name.toLowerCase()
|
|
||||||
if (iconMap[lower]) return iconMap[lower]
|
|
||||||
for (var key in iconMap) {
|
|
||||||
if (key.endsWith("*") && key.startsWith("*")) {
|
|
||||||
var middle = key.slice(1, -1)
|
|
||||||
if (lower.indexOf(middle) !== -1) return iconMap[key]
|
|
||||||
} else if (key.endsWith("*")) {
|
|
||||||
var prefix = key.slice(0, -1)
|
|
||||||
if (lower.startsWith(prefix)) return iconMap[key]
|
|
||||||
} else if (key.startsWith("*")) {
|
|
||||||
var suffix = key.slice(1)
|
|
||||||
if (lower.endsWith(suffix)) return iconMap[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: clientsProc
|
|
||||||
command: ["hyprctl", "clients", "-j"]
|
|
||||||
running: true
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
try {
|
|
||||||
var data = JSON.parse(this.text.trim())
|
|
||||||
var newIcons = {}
|
|
||||||
for (var i = 0; i < data.length; i++) {
|
|
||||||
var client = data[i]
|
|
||||||
var wid = client.workspace.id
|
|
||||||
var icon = root.matchIcon(client.initialTitle) || root.matchIcon(client.initialClass) || "\"" + client.initialTitle + "\""
|
|
||||||
if (icon) {
|
|
||||||
if (!newIcons[wid]) newIcons[wid] = []
|
|
||||||
newIcons[wid].push(icon)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
root.workspaceIcons = newIcons
|
|
||||||
} catch (e) {
|
|
||||||
// hyprctl output was not valid JSON
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
interval: 1000
|
|
||||||
running: true
|
|
||||||
repeat: true
|
|
||||||
triggeredOnStart: true
|
|
||||||
onTriggered: clientsProc.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property var iconMap: ({
|
|
||||||
// Youtube
|
|
||||||
"grayjay": "",
|
|
||||||
// Browser
|
|
||||||
"ablaze floorp": "",
|
|
||||||
"floorp": "",
|
|
||||||
"librewolf": "",
|
|
||||||
"midori": "",
|
|
||||||
"brave-browser": "",
|
|
||||||
"chromium": "",
|
|
||||||
// E-Mail
|
|
||||||
"*thunderbird": "",
|
|
||||||
// Terminals
|
|
||||||
"kitty": "",
|
|
||||||
"alacritty": "",
|
|
||||||
// Videoplayer
|
|
||||||
"vlc media player": "",
|
|
||||||
"mpv": "",
|
|
||||||
"ffplay": "",
|
|
||||||
// Video editing
|
|
||||||
"org.kde.kdenlive": "",
|
|
||||||
// Video
|
|
||||||
"*obs*": "",
|
|
||||||
"hyprland-share-picker": "",
|
|
||||||
// Chats
|
|
||||||
"discord": "",
|
|
||||||
"vesktop": "",
|
|
||||||
"signal": "",
|
|
||||||
"xyz.chatboxapp.app": "",
|
|
||||||
// Coding
|
|
||||||
"visual studio code": "",
|
|
||||||
"vscodium": "",
|
|
||||||
"jetbrains-idea": "",
|
|
||||||
"jetbrains-studio": "",
|
|
||||||
// Text Editor
|
|
||||||
"org.xfce.mousepad": "",
|
|
||||||
// Password
|
|
||||||
"org.keepassxc.keepassxc": "",
|
|
||||||
"yubico authenticator": "",
|
|
||||||
// Cloud
|
|
||||||
"com.nextcloud*": "",
|
|
||||||
// App Store
|
|
||||||
"octopi": "",
|
|
||||||
// Games
|
|
||||||
"steam*": "",
|
|
||||||
"org.prismlauncher*": "",
|
|
||||||
"minecraft*": "",
|
|
||||||
"game": "",
|
|
||||||
"eden*": "",
|
|
||||||
// Digital Arts
|
|
||||||
"blender": "",
|
|
||||||
// Image Editor
|
|
||||||
"gimp": "",
|
|
||||||
"*inkscape*": "",
|
|
||||||
"krita": "",
|
|
||||||
// VM
|
|
||||||
"virt*": "",
|
|
||||||
"remote-viewer": "",
|
|
||||||
// Audio
|
|
||||||
"*qpwgraph": "",
|
|
||||||
"carla": "",
|
|
||||||
"volume*": "",
|
|
||||||
"pavucontrol": "",
|
|
||||||
// Document Editor/Viewer
|
|
||||||
"libreoffice-startcenter": "",
|
|
||||||
"libreoffice-base": "",
|
|
||||||
"libreoffice-calc": "",
|
|
||||||
"libreoffice-draw": "",
|
|
||||||
"libreoffice-impress": "",
|
|
||||||
"libreoffice-math": "",
|
|
||||||
"libreoffice-writer": "",
|
|
||||||
"*rnote": "",
|
|
||||||
"xreader": "",
|
|
||||||
"*xournalpp*": "",
|
|
||||||
"qpdfview*": "",
|
|
||||||
// Hardware
|
|
||||||
"mission center": "",
|
|
||||||
"qdirstat": "",
|
|
||||||
"disks": "",
|
|
||||||
// File Manager
|
|
||||||
"nemo": "",
|
|
||||||
"org.gnome.nautilus": "",
|
|
||||||
"org.kde.dolphin": "",
|
|
||||||
"xdg-desktop-portal-gtk": "",
|
|
||||||
// Settings
|
|
||||||
"nwg-look": "",
|
|
||||||
"qt5ct": "",
|
|
||||||
"qt6ct": "",
|
|
||||||
"sddm-conf": "",
|
|
||||||
"org.gnome.Settings": "",
|
|
||||||
"blueman*": "",
|
|
||||||
"nm-connection-editor": "",
|
|
||||||
"nm-applet": "",
|
|
||||||
// Calculator
|
|
||||||
"calculator": "",
|
|
||||||
// VPN
|
|
||||||
"*vpn": "",
|
|
||||||
"*cisco*": "",
|
|
||||||
// Torrent
|
|
||||||
"*qbittorrent*": "",
|
|
||||||
// Hardware Design
|
|
||||||
"xilinx*": "",
|
|
||||||
"vsim": "",
|
|
||||||
"*ivado*": "",
|
|
||||||
// BoxBuddy
|
|
||||||
"*boxbuddy*": "",
|
|
||||||
// Stream
|
|
||||||
"fladder": "",
|
|
||||||
"crunchyroll": "",
|
|
||||||
"netflix": "",
|
|
||||||
"primevideo": "",
|
|
||||||
// Image Viewer
|
|
||||||
"viewnior": "",
|
|
||||||
// CNC
|
|
||||||
"lightburn": "",
|
|
||||||
"wofi": "",
|
|
||||||
// Screenshare
|
|
||||||
"moonlight": "ßß"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
singleton AppsState AppsState.qml
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
|
|
||||||
Item {
|
|
||||||
property bool available: false
|
|
||||||
property real percentage: 0
|
|
||||||
property bool charging: false
|
|
||||||
property real energy: 0
|
|
||||||
property real voltage: 0
|
|
||||||
property int charge_cycle: 0
|
|
||||||
property real time_to_empty: 0
|
|
||||||
property real energy_rate: 0
|
|
||||||
|
|
||||||
function parseUpower(line) {
|
|
||||||
line = line.trim()
|
|
||||||
if (line.startsWith("percentage:")) {
|
|
||||||
percentage = parseInt(line.split(":")[1])
|
|
||||||
// console.log("percentage =", percentage)
|
|
||||||
}
|
|
||||||
else if (line.startsWith("state:")) {
|
|
||||||
charging = !line.includes("discharging")
|
|
||||||
// console.log("charging =", charging)
|
|
||||||
}
|
|
||||||
else if (line.startsWith("energy:")) {
|
|
||||||
energy = parseFloat(line.split(":")[1])
|
|
||||||
// console.log("energy =", energy)
|
|
||||||
}
|
|
||||||
else if (line.startsWith("voltage:")) {
|
|
||||||
voltage = parseFloat(line.split(":")[1])
|
|
||||||
// console.log("voltage =", voltage)
|
|
||||||
}
|
|
||||||
else if (line.startsWith("energy-rate:")) {
|
|
||||||
energy_rate = parseFloat(line.split(":")[1])
|
|
||||||
// console.log("energy_rate =", energy_rate)
|
|
||||||
}
|
|
||||||
else if (line.startsWith("charge-cycles:")) {
|
|
||||||
charge_cycle = parseInt(line.split(":")[1])
|
|
||||||
// console.log("charge_cycle =", charge_cycle)
|
|
||||||
}
|
|
||||||
else if (line.startsWith("time to empty:")) {
|
|
||||||
time_to_empty = parseFloat(line.split(":")[1])
|
|
||||||
// console.log("time_to_empty =", time_to_empty)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: upowerProc
|
|
||||||
command: ["bash", "-c", "upower -i $(upower -e | grep '^/org/freedesktop/UPower/devices/battery')"]
|
|
||||||
stdout: SplitParser {
|
|
||||||
onRead: function(data) {
|
|
||||||
parseUpower(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: batteryAvailable
|
|
||||||
command: ["sh", "-c", "upower -e | grep -q '^/org/freedesktop/UPower/devices/battery' && echo '1' || echo '0'"]
|
|
||||||
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
const hasBattery = this.text.trim() === "1"
|
|
||||||
available = hasBattery
|
|
||||||
if (hasBattery) {
|
|
||||||
pollTimer.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: pollTimer
|
|
||||||
interval: 1000
|
|
||||||
running: false
|
|
||||||
repeat: true
|
|
||||||
triggeredOnStart: false
|
|
||||||
onTriggered: upowerProc.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
batteryAvailable.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
singleton BatteryState 1.0 BatteryState.qml
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string shortDate: Qt.formatDate(new Date(), "dd.MM.yyyy - ")
|
|
||||||
property string fullDate: Qt.formatDate(new Date(), "dddd, MMMM d, yyyy")
|
|
||||||
property string currentTime: Qt.formatTime(new Date(), "hh:mm:ss")
|
|
||||||
property string uptime: "Uptime: ..."
|
|
||||||
property bool expanded: false
|
|
||||||
|
|
||||||
property Timer timeTimer: Timer {
|
|
||||||
interval: 1000
|
|
||||||
running: true
|
|
||||||
repeat: true
|
|
||||||
triggeredOnStart: true
|
|
||||||
onTriggered: root.currentTime = Qt.formatTime(new Date(), "hh:mm:ss")
|
|
||||||
}
|
|
||||||
|
|
||||||
property Timer dateTimer: Timer {
|
|
||||||
interval: 60000
|
|
||||||
running: true
|
|
||||||
repeat: true
|
|
||||||
triggeredOnStart: true
|
|
||||||
onTriggered: {
|
|
||||||
root.shortDate = Qt.formatDate(new Date(), "dd.MM.yyyy - ")
|
|
||||||
root.fullDate = Qt.formatDate(new Date(), "dddd, MMMM d, yyyy")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
property Process sysInfoProcess: Process {
|
|
||||||
command: ["sh", "-c", "echo $(cat /proc/uptime)"]
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
var uptimeSecs = parseFloat(text.trim().split(" ")[0])
|
|
||||||
var days = Math.floor(uptimeSecs / 86400)
|
|
||||||
var hours = Math.floor((uptimeSecs % 86400) / 3600)
|
|
||||||
var mins = Math.floor((uptimeSecs % 3600) / 60)
|
|
||||||
root.uptime = "Uptime: " + days + "d " + hours + "h " + mins + "m"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
property Timer sysInfoTimer: Timer {
|
|
||||||
interval: 10000
|
|
||||||
running: true
|
|
||||||
repeat: true
|
|
||||||
triggeredOnStart: true
|
|
||||||
onTriggered: root.sysInfoProcess.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
singleton ClockState ClockState.qml
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
import "../../../../config"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
property int idle: 0
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: statusScript
|
|
||||||
command: ["sh", "-c", Config.configDir + "/modules/bar/scripts/Idle.sh --status"]
|
|
||||||
running: true
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
idle = this.text.trim() === "0" ? 1 : 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
interval: 5000
|
|
||||||
running: true
|
|
||||||
repeat: true
|
|
||||||
triggeredOnStart: true
|
|
||||||
onTriggered: statusScript.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
singleton IdleState 1.0 IdleState.qml
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
import "../../../../config"
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string status: "..."
|
|
||||||
|
|
||||||
property string interfaceName: ""
|
|
||||||
property string interfaceType: ""
|
|
||||||
property string connectionName: ""
|
|
||||||
property string ipv4: ""
|
|
||||||
property string wifiName: ""
|
|
||||||
property string signalStrength: ""
|
|
||||||
property string wifiChannel: ""
|
|
||||||
property string wifiFrequency: ""
|
|
||||||
property string linkSpeed: ""
|
|
||||||
property string downloadSpeed: ""
|
|
||||||
property string uploadSpeed: ""
|
|
||||||
property string ping: ""
|
|
||||||
property bool internetAvailable: false
|
|
||||||
property bool vpnConnected: false
|
|
||||||
property string vpnName: ""
|
|
||||||
property string vpnIp: ""
|
|
||||||
property bool tailscaleConnected: false
|
|
||||||
property string tailscaleIp: ""
|
|
||||||
|
|
||||||
property bool running: false
|
|
||||||
|
|
||||||
property string _activeDevice: ""
|
|
||||||
property real _prevRxBytes: 0
|
|
||||||
property real _prevTxBytes: 0
|
|
||||||
property var _prevUpdateTime: 0
|
|
||||||
|
|
||||||
property Timer networkTimer: Timer {
|
|
||||||
interval: 10000
|
|
||||||
repeat: true
|
|
||||||
running: true
|
|
||||||
onTriggered: networkScript.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
property Process networkScript: Process {
|
|
||||||
command: ["sh", "-c",
|
|
||||||
"echo '===SHOW==='; " +
|
|
||||||
"ACTIVE=$(nmcli -t device status 2>/dev/null | awk -F: '$3==\"connected\"{print $1; exit}'); " +
|
|
||||||
"echo \"ACTIVE_DEVICE=$ACTIVE\"; " +
|
|
||||||
"if [ -n \"$ACTIVE\" ]; then " +
|
|
||||||
" nmcli -t -f ALL device show \"$ACTIVE\" 2>/dev/null; " +
|
|
||||||
"fi; " +
|
|
||||||
"echo '===TRAFFIC==='; " +
|
|
||||||
"if [ -n \"$ACTIVE\" ]; then " +
|
|
||||||
" echo \"RX_BYTES=$(cat /sys/class/net/$ACTIVE/statistics/rx_bytes 2>/dev/null || echo 0)\"; " +
|
|
||||||
" echo \"TX_BYTES=$(cat /sys/class/net/$ACTIVE/statistics/tx_bytes 2>/dev/null || echo 0)\"; " +
|
|
||||||
"fi; " +
|
|
||||||
"echo '===WIFI==='; " +
|
|
||||||
"nmcli -t -f active,ssid,signal,chan,freq,rate dev wifi | awk -F: '$1==\"yes\" { $1=\"\"; sub(/^:/,\"\"); print }'; " +
|
|
||||||
"echo '===PING==='; " +
|
|
||||||
"ping -c 1 -W 2 1.1.1.1 2>/dev/null | awk -F/ '/rtt/{print $5}' || echo ''; " +
|
|
||||||
"echo '===INTERNET==='; " +
|
|
||||||
"ping -c 1 -W 1 1.1.1.1 2>/dev/null >/dev/null && echo 1 || echo 0; " +
|
|
||||||
"echo '===VPN==='; " +
|
|
||||||
"nmcli -t -f NAME,TYPE connection show --active 2>/dev/null | grep -i vpn || true; " +
|
|
||||||
"echo '===TAILSCALE==='; " +
|
|
||||||
"TAIL_IP=$(ip -4 addr show tailscale0 2>/dev/null | grep -oP 'inet \\K[\\d.]+'); " +
|
|
||||||
"if [ -n \"$TAIL_IP\" ]; then echo \"TAILSCALE_IP=$TAIL_IP\"; else echo \"\"; fi"
|
|
||||||
]
|
|
||||||
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: root.parseNetworkOutput(text.trim())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatSpeed(bytesPerSec) {
|
|
||||||
if (bytesPerSec >= 1073741824) return (bytesPerSec / 1073741824).toFixed(1) + " GB/s"
|
|
||||||
if (bytesPerSec >= 1048576) return (bytesPerSec / 1048576).toFixed(1) + " MB/s"
|
|
||||||
if (bytesPerSec >= 1024) return (bytesPerSec / 1024).toFixed(1) + " KB/s"
|
|
||||||
return bytesPerSec.toFixed(0) + " B/s"
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseNetworkOutput(output) {
|
|
||||||
var sections = output.split("===TAILSCALE===")
|
|
||||||
var tailscaleSection = sections.length > 1 ? sections[1].trim() : ""
|
|
||||||
|
|
||||||
var beforeTailscale = sections[0]
|
|
||||||
sections = beforeTailscale.split("===VPN===")
|
|
||||||
var vpnSection = sections.length > 1 ? sections[1].trim() : ""
|
|
||||||
|
|
||||||
var beforeVpn = sections[0]
|
|
||||||
sections = beforeVpn.split("===INTERNET===")
|
|
||||||
root.internetAvailable = sections.length > 1 ? sections[1].trim() === "1" : false
|
|
||||||
|
|
||||||
var beforeInternet = sections[0]
|
|
||||||
sections = beforeInternet.split("===PING===")
|
|
||||||
root.ping = sections.length > 1 ? sections[1].trim() : ""
|
|
||||||
|
|
||||||
var beforePing = sections[0]
|
|
||||||
sections = beforePing.split("===WIFI===")
|
|
||||||
var wifiSection = sections.length > 1 ? sections[1].trim() : ""
|
|
||||||
|
|
||||||
var beforeWifi = sections[0]
|
|
||||||
sections = beforeWifi.split("===TRAFFIC===")
|
|
||||||
var trafficSection = sections.length > 1 ? sections[1].trim() : ""
|
|
||||||
|
|
||||||
var beforeTraffic = sections[0]
|
|
||||||
sections = beforeTraffic.split("===SHOW===")
|
|
||||||
var showSection = sections.length > 1 ? sections[1].trim() : ""
|
|
||||||
|
|
||||||
// Parse SHOW section
|
|
||||||
var activeDevice = ""
|
|
||||||
var lines = showSection.split("\n")
|
|
||||||
for (var i = 0; i < lines.length; i++) {
|
|
||||||
var line = lines[i].trim()
|
|
||||||
if (line.indexOf("ACTIVE_DEVICE=") === 0) {
|
|
||||||
activeDevice = line.substring("ACTIVE_DEVICE=".length)
|
|
||||||
} else if (line.indexOf("GENERAL.DEVICE:") === 0) {
|
|
||||||
root.interfaceName = line.substring("GENERAL.DEVICE:".length)
|
|
||||||
} else if (line.indexOf("GENERAL.TYPE:") === 0) {
|
|
||||||
root.interfaceType = line.substring("GENERAL.TYPE:".length)
|
|
||||||
} else if (line.indexOf("GENERAL.CONNECTION:") === 0) {
|
|
||||||
root.connectionName = line.substring("GENERAL.CONNECTION:".length)
|
|
||||||
} else if (line.indexOf("IP4.ADDRESS") >= 0) {
|
|
||||||
var ipPart = line.substring(line.indexOf(":") + 1)
|
|
||||||
root.ipv4 = ipPart.split("/")[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse TRAFFIC section
|
|
||||||
if (trafficSection) {
|
|
||||||
var trafficLines = trafficSection.split("\n")
|
|
||||||
var rxBytes = 0
|
|
||||||
var txBytes = 0
|
|
||||||
for (var t = 0; t < trafficLines.length; t++) {
|
|
||||||
var tline = trafficLines[t].trim()
|
|
||||||
if (tline.indexOf("RX_BYTES=") === 0) rxBytes = parseFloat(tline.substring("RX_BYTES=".length))
|
|
||||||
else if (tline.indexOf("TX_BYTES=") === 0) txBytes = parseFloat(tline.substring("TX_BYTES=".length))
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log("[Network] rxBytes:", rxBytes, "txBytes:", txBytes)
|
|
||||||
// console.log("[Network] activeDevice:", activeDevice, "| prevActiveDevice:", root._activeDevice)
|
|
||||||
// console.log("[Network] prevRxBytes:", root._prevRxBytes, "prevTxBytes:", root._prevTxBytes, "prevTime:", root._prevUpdateTime)
|
|
||||||
|
|
||||||
if (activeDevice === root._activeDevice && root._prevRxBytes > 0 && root._prevUpdateTime > 0) {
|
|
||||||
var now = Date.now()
|
|
||||||
var interval = (now - root._prevUpdateTime) / 1000
|
|
||||||
// console.log("[Network] Same device, interval:", interval, "s")
|
|
||||||
// console.log("[Network] rxDelta:", (rxBytes - root._prevRxBytes), "txDelta:", (txBytes - root._prevTxBytes))
|
|
||||||
if (interval > 0) {
|
|
||||||
var downBps = (rxBytes - root._prevRxBytes) / interval
|
|
||||||
var upBps = (txBytes - root._prevTxBytes) / interval
|
|
||||||
// console.log("[Network] downBps:", downBps, "upBps:", upBps)
|
|
||||||
root.downloadSpeed = root.formatSpeed(downBps)
|
|
||||||
root.uploadSpeed = root.formatSpeed(upBps)
|
|
||||||
// console.log("[Network] downloadSpeed:", root.downloadSpeed, "uploadSpeed:", root.uploadSpeed)
|
|
||||||
} else {
|
|
||||||
console.log("[Network] Interval zero or negative, skipping")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// console.log("[Network] First run or device changed, storing baseline")
|
|
||||||
root.downloadSpeed = ""
|
|
||||||
root.uploadSpeed = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
root._activeDevice = activeDevice
|
|
||||||
root._prevRxBytes = rxBytes
|
|
||||||
root._prevTxBytes = txBytes
|
|
||||||
root._prevUpdateTime = Date.now()
|
|
||||||
// console.log("[Network] Stored baseline: rxBytes:", root._prevRxBytes, "txBytes:", root._prevTxBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse WIFI section
|
|
||||||
if (wifiSection) {
|
|
||||||
var wifiParts = wifiSection.split(" ")
|
|
||||||
if (wifiParts.length >= 2) {
|
|
||||||
root.wifiName = wifiParts[0] || ""
|
|
||||||
root.signalStrength = wifiParts[1] || ""
|
|
||||||
if (wifiParts.length >= 3) root.wifiChannel = wifiParts[2] || ""
|
|
||||||
if (wifiParts.length >= 4) root.wifiFrequency = wifiParts[3] + " " + wifiParts[4] || ""
|
|
||||||
if (wifiParts.length >= 5) root.linkSpeed = wifiParts[5] + " " + wifiParts[6] || ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine status icon
|
|
||||||
if (root.interfaceType === "ethernet") {
|
|
||||||
root.status = ""
|
|
||||||
} else if (root.interfaceType === "wifi") {
|
|
||||||
if (!root.connectionName) {
|
|
||||||
root.status = ""
|
|
||||||
} else {
|
|
||||||
var sig = parseInt(root.signalStrength)
|
|
||||||
if (sig > 80) root.status = ""
|
|
||||||
else if (sig > 60) root.status = ""
|
|
||||||
else if (sig > 40) root.status = ""
|
|
||||||
else if (sig > 20) root.status = ""
|
|
||||||
else root.status = ""
|
|
||||||
}
|
|
||||||
} else if (!activeDevice) {
|
|
||||||
root.status = "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse VPN section
|
|
||||||
if (vpnSection) {
|
|
||||||
root.vpnConnected = true
|
|
||||||
var vpnLines = vpnSection.split("\n")
|
|
||||||
if (vpnLines.length > 0) {
|
|
||||||
var vpnParts = vpnLines[0].split(":")
|
|
||||||
root.vpnName = vpnParts[0] || ""
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
root.vpnConnected = false
|
|
||||||
root.vpnName = ""
|
|
||||||
root.vpnIp = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse TAILSCALE section
|
|
||||||
if (tailscaleSection && tailscaleSection.indexOf("TAILSCALE_IP=") === 0) {
|
|
||||||
root.tailscaleConnected = true
|
|
||||||
root.tailscaleIp = tailscaleSection.substring("TAILSCALE_IP=".length)
|
|
||||||
} else {
|
|
||||||
root.tailscaleConnected = false
|
|
||||||
root.tailscaleIp = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
networkScript.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
singleton NetworkState NetworkState.qml
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import "../../../config"
|
|
||||||
|
|
||||||
PopupWindow {
|
|
||||||
id: popup
|
|
||||||
|
|
||||||
property Item anchorItem
|
|
||||||
property bool anchorHovered: false
|
|
||||||
property int minpopupWidth: 150
|
|
||||||
property int minpopupHeight: 50
|
|
||||||
property int popupVerticalOffset: 0
|
|
||||||
property int spacingValue: 12
|
|
||||||
property int radiusValue: 12
|
|
||||||
|
|
||||||
default property alias content: contentColumn.data
|
|
||||||
|
|
||||||
visible: false
|
|
||||||
color: "transparent"
|
|
||||||
implicitWidth: Math.max(popup.minpopupWidth, contentColumn.implicitWidth + 2 * popup.spacingValue)
|
|
||||||
implicitHeight: Math.max(popup.minpopupHeight, contentColumn.implicitHeight + 2 * popup.spacingValue)
|
|
||||||
|
|
||||||
onAnchorHoveredChanged: popup.updateVisibility()
|
|
||||||
|
|
||||||
function updateVisibility() {
|
|
||||||
if (anchorHovered || mouseArea.containsMouse) {
|
|
||||||
closeTimer.stop()
|
|
||||||
visible = true
|
|
||||||
} else {
|
|
||||||
closeTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: closeTimer
|
|
||||||
interval: 1
|
|
||||||
onTriggered: {
|
|
||||||
if (!anchorHovered && !mouseArea.containsMouse) {
|
|
||||||
visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anchor {
|
|
||||||
item: anchorItem
|
|
||||||
edges: Edges.Top | Edges.Left
|
|
||||||
gravity: Edges.Bottom | Edges.Right
|
|
||||||
adjustment: PopupAdjustment.FlipY | PopupAdjustment.SlideX
|
|
||||||
onAnchoring: {
|
|
||||||
anchor.rect.x = (anchorItem.width - popup.width) / 2
|
|
||||||
anchor.rect.y = anchorItem.height + popupVerticalOffset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
onContainsMouseChanged: popup.updateVisibility()
|
|
||||||
Rectangle {
|
|
||||||
id: background
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Qt.alpha(Colors.primaryContainer, 0.9)
|
|
||||||
radius: popup.radiusValue
|
|
||||||
border {
|
|
||||||
color: Colors.primaryContainer_fg
|
|
||||||
width: Config.border_width
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: contentColumn
|
|
||||||
width: implicitWidth
|
|
||||||
height: implicitHeight
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
margins: popup.spacingValue
|
|
||||||
}
|
|
||||||
spacing: popup.spacingValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Io
|
|
||||||
import "../../../config"
|
|
||||||
import "../states/Battery"
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: batteryButton
|
|
||||||
width: expanded ? Math.max(expandedRow.width + Config.spacing_fun(height)*3, bar.height) : Math.max(batteryText.width + Config.spacing_fun(height)*2, bar.height)
|
|
||||||
height: bar.height
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
visible: BatteryState.available
|
|
||||||
|
|
||||||
property bool expanded: false
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: batteryButton.containsMouse ? Colors.tertiary : Qt.alpha(Colors.tertiaryContainer, 0.25)
|
|
||||||
radius: Config.radius_fun(batteryButton.height)
|
|
||||||
border.width: Config.border_width
|
|
||||||
border.color: batteryButton.containsMouse ? Colors.tertiaryContainer_fg
|
|
||||||
: Colors.secondaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: batteryText
|
|
||||||
visible : !expanded
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text:(
|
|
||||||
BatteryState.percentage >= 90 ? "" :
|
|
||||||
BatteryState.percentage >= 60 ? "" :
|
|
||||||
BatteryState.percentage >= 30 ? "" :
|
|
||||||
BatteryState.percentage >= 10 ? "" :
|
|
||||||
""
|
|
||||||
)
|
|
||||||
font.pixelSize: Config.font_size(batteryButton.height)
|
|
||||||
font.family: Config.font
|
|
||||||
color: (
|
|
||||||
BatteryState.charging ? (
|
|
||||||
BatteryState.percentage == 100 ? Colors.secondary :
|
|
||||||
Colors.tertiary
|
|
||||||
) :
|
|
||||||
BatteryState.percentage <= 5 ? Colors.errorContainer :
|
|
||||||
BatteryState.percentage < 10 ? "yellow" :
|
|
||||||
batteryButton.containsMouse ? Colors.tertiary_fg :
|
|
||||||
Colors.primary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: chargeIcon
|
|
||||||
visible : !expanded && BatteryState.charging
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: ""
|
|
||||||
font.pixelSize: Config.iconSize(batteryButton.height)
|
|
||||||
font.family: Config.font
|
|
||||||
style: Text.Outline
|
|
||||||
styleColor: Qt.alpha(Colors.tertiaryContainer, 0.5)
|
|
||||||
color: Colors.tertiary
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: expandedRow
|
|
||||||
visible: expanded
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Config.spacing_fun(batteryButton.height)
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: batteryPercentageSymbol
|
|
||||||
text: (
|
|
||||||
BatteryState.charging ? "" :
|
|
||||||
BatteryState.percentage >= 90 ? "":
|
|
||||||
BatteryState.percentage >= 80 ? "":
|
|
||||||
BatteryState.percentage >= 70 ? "":
|
|
||||||
BatteryState.percentage >= 60 ? "":
|
|
||||||
BatteryState.percentage >= 50 ? "":
|
|
||||||
BatteryState.percentage >= 40 ? "":
|
|
||||||
BatteryState.percentage >= 30 ? "":
|
|
||||||
BatteryState.percentage >= 20 ? "":
|
|
||||||
BatteryState.percentage >= 10 ? "":
|
|
||||||
BatteryState.percentage >= 5 ? "":
|
|
||||||
""
|
|
||||||
)
|
|
||||||
|
|
||||||
font.pixelSize: Config.labelSize(batteryButton.height)
|
|
||||||
font.family: Config.font
|
|
||||||
font.bold: true
|
|
||||||
|
|
||||||
color: (
|
|
||||||
BatteryState.percentage <= 5 ? Colors.errorContainer :
|
|
||||||
BatteryState.charging ? (
|
|
||||||
BatteryState.percentage == 100 ? Colors.secondary :
|
|
||||||
Colors.tertiary
|
|
||||||
) :
|
|
||||||
BatteryState.percentage < 10 ? "yellow" :
|
|
||||||
batteryButton.containsMouse ? Colors.tertiary_fg :
|
|
||||||
Colors.primary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: batteryPercentageText
|
|
||||||
text: BatteryState.percentage + "%"
|
|
||||||
|
|
||||||
font.pixelSize: Config.labelSize(batteryButton.height)
|
|
||||||
font.family: Config.font
|
|
||||||
font.bold: true
|
|
||||||
|
|
||||||
color: batteryPercentageSymbol.color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
expanded = !expanded
|
|
||||||
console.log("[Battery] Expanded: " + expanded + ", percentage: " + BatteryState.percentage + "%, charging: " + BatteryState.charging)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BarPopup {
|
|
||||||
id: batteryPopup
|
|
||||||
anchorItem: batteryButton
|
|
||||||
anchorHovered: batteryButton.containsMouse
|
|
||||||
spacingValue: Config.spacing_fun(batteryButton.height)
|
|
||||||
radiusValue: Config.radius_fun(batteryButton.height)
|
|
||||||
|
|
||||||
Column {
|
|
||||||
spacing: parent.spacing
|
|
||||||
Text {
|
|
||||||
text: "percentage: " + BatteryState.percentage + "%"
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: "charging: " + BatteryState.charging
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: "energy: " + BatteryState.energy
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: "voltage: " + BatteryState.voltage
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: "charge_cycle: " + BatteryState.charge_cycle
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: "time_to_empty: " + BatteryState.time_to_empty + "h"
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: "energy_rate: " + BatteryState.energy_rate + "W"
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +1,36 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import "../../../config"
|
import "../../../colors"
|
||||||
import "../states/Clock"
|
|
||||||
|
|
||||||
Rectangle { //workspace
|
Rectangle { //workspace
|
||||||
id: clockRect
|
width: timeDisplay.width + 16
|
||||||
width: ClockState.expanded ? Math.max(dateText.width + timeText.width + Config.spacing_fun(height)*3, bar.height) : Math.max(timeText.width + Config.spacing_fun(height)*2, bar.height)
|
height: timeDisplay.height + 16
|
||||||
height: bar.height
|
radius: 4
|
||||||
radius: Config.radius_fun(height)
|
color: Colors.primaryContainer
|
||||||
color: clockArea.containsMouse ? Colors.tertiaryContainer : Colors.primaryContainer
|
border.color: Colors.primaryContainer_fg
|
||||||
border.color: (
|
border.width: 2
|
||||||
clockArea.containsMouse ? Colors.tertiaryContainer_fg :
|
|
||||||
Colors.primaryContainer_fg
|
|
||||||
)
|
|
||||||
border.width: Config.border_width
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: clockArea
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
|
||||||
onClicked: {
|
|
||||||
ClockState.expanded = !ClockState.expanded
|
|
||||||
console.log("[Clock] Date visible: " + ClockState.expanded)
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: dateText
|
id: timeDisplay
|
||||||
text: ClockState.shortDate
|
|
||||||
visible: ClockState.expanded
|
|
||||||
color: (
|
|
||||||
clockArea.containsMouse ? Colors.tertiary :
|
|
||||||
Colors.primary
|
|
||||||
)
|
|
||||||
font.pixelSize: Config.font_size_small(clockRect.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: timeText
|
|
||||||
property string currentTime: ""
|
property string currentTime: ""
|
||||||
|
|
||||||
text: ClockState.currentTime
|
text: currentTime
|
||||||
color: (
|
|
||||||
clockArea.containsMouse ? Colors.tertiary :
|
|
||||||
Colors.primary
|
|
||||||
)
|
|
||||||
font.pixelSize: Config.font_size_small(clockRect.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BarPopup {
|
|
||||||
id: clockPopup
|
|
||||||
anchorItem: clockRect
|
|
||||||
anchorHovered: clockArea.containsMouse
|
|
||||||
spacingValue: Config.spacing_fun(clockRect.height)
|
|
||||||
radiusValue: Config.radius_fun(clockRect.height)
|
|
||||||
|
|
||||||
Column {
|
|
||||||
spacing: parent.spacing
|
|
||||||
Text {
|
|
||||||
text: ClockState.shortDate + ClockState.currentTime
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
color: Colors.primary
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
font.pixelSize: 18
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
font.family: "Inter, sans-serif"
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
anchors.centerIn: parent
|
||||||
text: ClockState.fullDate
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//Update time every second
|
||||||
Text {
|
Timer {
|
||||||
text: ClockState.uptime
|
interval: 1000
|
||||||
wrapMode: Text.WordWrap
|
running: true
|
||||||
color: Colors.primary
|
repeat: true
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
onTriggered: {
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
var now = new Date()
|
||||||
font.family: Config.font
|
timeDisplay.currentTime = Qt.formatTime(now, "hh:mm:ss")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Io
|
|
||||||
import "../../../config"
|
|
||||||
import "../states/Idle"
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: idleButton
|
|
||||||
width: Math.max(idleText.width + Config.spacing_fun(height)*2, height)
|
|
||||||
height: bar.height
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
var newState = IdleState.idle ? 0 : 1
|
|
||||||
console.log("[IdleButton] Toggling idle: " + (newState ? "enabled" : "disabled"))
|
|
||||||
idleToggleProc.startDetached()
|
|
||||||
IdleState.idle = newState
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: idleButton.containsMouse ? Colors.tertiary : Qt.alpha(Colors.tertiaryContainer, 0.25)
|
|
||||||
radius: Config.radius_fun(idleButton.height)
|
|
||||||
border.width: Config.border_width
|
|
||||||
border.color: (
|
|
||||||
idleButton.containsMouse ? Colors.tertiaryContainer_fg :
|
|
||||||
Colors.secondaryContainer_fg
|
|
||||||
)
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: idleText
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: IdleState.idle ? "" : ""
|
|
||||||
font.pixelSize: Config.iconSize(idleButton.height)
|
|
||||||
font.family: Config.font
|
|
||||||
color: (
|
|
||||||
idleButton.containsMouse ? Colors.tertiary_fg :
|
|
||||||
IdleState.idle ? Colors.tertiary
|
|
||||||
: Colors.primary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: idleToggleProc
|
|
||||||
command: ["sh", "-c", Config.configDir + "/modules/bar/scripts/Idle.sh"]
|
|
||||||
running: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +1,26 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Hyprland
|
||||||
import "../../../config"
|
import "../../../colors"
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: menuButton
|
id: archButton
|
||||||
width: Math.max(bar.height, menuText.width + Config.spacing)
|
width: 30
|
||||||
height: bar.height
|
height: 28
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
menuProc.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "transparent"
|
color: archButton.containsMouse ? Colors.tertiary : Qt.alpha(Colors.primaryContainer, 0.25)
|
||||||
radius: Config.radius_fun(menuButton.height)
|
radius: 6
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: menuText
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: ""
|
text: ""
|
||||||
font.pixelSize: Config.bigIconSize(menuButton.height)
|
font.pixelSize: 26
|
||||||
font.family: Config.font
|
font.family: "Nerd Font"
|
||||||
color: Colors.secondaryContainer_fg
|
color: archButton.containsMouse ? Colors.tertiary_fg : Colors.primary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
|
||||||
id: menuProc
|
|
||||||
command: ["sh", "-c", "wofi --show drun"]
|
|
||||||
running: false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+28
-186
@@ -1,210 +1,52 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import "../../../config"
|
import Quickshell.Hyprland
|
||||||
import "../states/Network"
|
import Quickshell.Io
|
||||||
|
import "../../../colors"
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: networkButton
|
id: networkButton
|
||||||
|
width: output.width + 16
|
||||||
width: Math.max(networkText.width + Config.spacing_fun(height)*2, height)
|
|
||||||
height: bar.height
|
height: bar.height
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
console.log("[Network] Refreshing... current status: " + NetworkState.status)
|
networkStatus.running = true
|
||||||
NetworkState.networkScript.running = false
|
|
||||||
NetworkState.networkScript.running = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: networkButton.containsMouse ? Colors.tertiary : Qt.alpha(Colors.tertiaryContainer, 0.25)
|
color: networkButton.containsMouse ? Colors.tertiary : Qt.alpha(Colors.tertiaryContainer, 0.25)
|
||||||
radius: Config.radius_fun(networkButton.height)
|
radius: 6
|
||||||
border.width: Config.border_width
|
width: output.width + 16
|
||||||
border.color: networkButton.containsMouse ? Colors.tertiaryContainer_fg
|
|
||||||
: Colors.secondaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: networkText
|
id: output
|
||||||
text: NetworkState.status
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
font.pixelSize: Config.iconSize(bar.height)
|
font.pixelSize: 26
|
||||||
font.family: Config.font
|
font.family: "Nerd Font"
|
||||||
color: networkButton.containsMouse ? Colors.tertiary_fg : networkText.text === " /" ? Colors.error : Colors.primary
|
color: networkButton.containsMouse ? Colors.tertiary_fg : output.text === " /" ? Colors.error : Colors.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: networkStatus
|
||||||
|
command: ["sh", "-c", Quickshell.env("HOME") + "/.config/quickshell/modules/bar/scripts/Network.sh"]
|
||||||
|
running: true
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
output.text = this.text.trim()
|
||||||
|
console.log("networkScript output:", this.text.trim())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BarPopup {
|
Timer {
|
||||||
id: clockPopup
|
interval: 10000
|
||||||
anchorItem: networkButton
|
running: true
|
||||||
anchorHovered: networkButton.containsMouse
|
repeat: true
|
||||||
spacingValue: Config.spacing_fun(networkButton.height)
|
onTriggered: networkStatus.running = true
|
||||||
radiusValue: Config.radius_fun(networkButton.height)
|
|
||||||
|
|
||||||
Column {
|
|
||||||
spacing: parent.spacing
|
|
||||||
Text {
|
|
||||||
text: "interfaceName: " + NetworkState.interfaceName
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "interfaceType: " + NetworkState.interfaceType
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "connectionName: " + NetworkState.connectionName
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "ipv4: " + NetworkState.ipv4
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "wifiName: " + NetworkState.wifiName
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "signalStrength: " + NetworkState.signalStrength
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "wifiChannel: " + NetworkState.wifiChannel
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "wifiFrequency: " + NetworkState.wifiFrequency
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "linkSpeed: " + NetworkState.linkSpeed
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "downloadSpeed: " + NetworkState.downloadSpeed
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "uploadSpeed: " + NetworkState.uploadSpeed
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "ping: " + NetworkState.ping
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "internetAvailable: " + NetworkState.internetAvailable
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "vpnConnected: " + NetworkState.vpnConnected
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "vpnName: " + NetworkState.vpnName
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "vpnIp: " + NetworkState.vpnIp
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "tailscaleConnected: " + NetworkState.tailscaleConnected
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "tailscaleIp: " + NetworkState.tailscaleIp
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Colors.primary
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pixelSize: Config.font_size_tiny(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,31 +1,48 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import "../../../config"
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Io
|
||||||
|
import "../../../colors"
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: powerButton
|
id: powerButton
|
||||||
width: Math.max(powerText.width + Config.spacing_fun(height), height)
|
width: powerText.width + 16
|
||||||
height: bar.height
|
height: bar.height
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
console.log("[PowerButton] Opening wlogout")
|
|
||||||
root.openWlogout()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: powerButton.containsMouse ? Colors.secondaryContainer_fg : Qt.alpha(Colors.secondary, 0.75)
|
color: powerButton.containsMouse ? Colors.secondaryContainer_fg : Qt.alpha(Colors.secondary, 0.5)
|
||||||
radius: Config.radius_fun(powerButton.height)
|
radius: 6
|
||||||
border.width: 0
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
Process {
|
||||||
|
id: powerOff
|
||||||
|
command: ["wlogout", "-b", "2"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: console.log(`line read: ${this.text}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
console.log("Running PowerOff Menu")
|
||||||
|
powerOff.startDetached()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: powerText
|
id: powerText
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: ""
|
text: ""
|
||||||
font.pixelSize: Config.bigIconSize(bar.height)
|
font.pixelSize: 26
|
||||||
font.family: Config.font
|
font.family: "Nerd Font"
|
||||||
color:powerButton.containsMouse ? Colors.secondaryContainer : Colors.secondary_fg
|
color:powerButton.containsMouse ? Colors.secondaryContainer : Colors.secondary_fg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,24 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
import Quickshell.Services.SystemTray
|
import Quickshell.Services.SystemTray
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import "../../../config"
|
import "../../../colors"
|
||||||
|
|
||||||
|
|
||||||
Row { // Workspace Row
|
Row { // Workspace Row
|
||||||
id: trayRow
|
id: trayRow
|
||||||
spacing: Config.small_spacing_fun(height)
|
spacing: 8
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: SystemTray.items
|
model: SystemTray.items
|
||||||
Column{
|
|
||||||
Item {
|
|
||||||
width: 1
|
|
||||||
height: Math.floor((bar.height - trayItem.height) / 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle { //trayItem
|
Rectangle { //trayItem
|
||||||
id: trayItem
|
id: trayItem
|
||||||
width: iconImage.width + Config.spacing_fun(bar.height)
|
width: bar.height
|
||||||
height: iconImage.height + Config.spacing_fun(bar.height)
|
height: bar.height
|
||||||
radius: Config.radius_fun(trayRow.height)
|
radius: 4
|
||||||
color: trayArea.containsMouse ? Colors.tertiaryContainer
|
color: "transparent"
|
||||||
: modelData.active ? Colors.primaryContainer
|
border.width: 2
|
||||||
: Colors.secondaryContainer
|
|
||||||
border.width: Config.border_width
|
|
||||||
border.color: trayArea.containsMouse ? Colors.tertiaryContainer_fg
|
|
||||||
: Colors.secondaryContainer_fg
|
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: steamRunner
|
id: steamRunner
|
||||||
@@ -36,96 +27,66 @@ Row { // Workspace Row
|
|||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: trayArea
|
id: workspaceButton
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||||
property int clickX: 0
|
|
||||||
property int clickY: 0
|
|
||||||
onClicked: (mouse) => {
|
onClicked: (mouse) => {
|
||||||
switch (mouse.button) {
|
switch (mouse.button) {
|
||||||
case Qt.LeftButton:
|
case Qt.LeftButton:
|
||||||
console.log("[Tray] Activate: " + modelData.title)
|
if (!modelData.onlyMenu) {
|
||||||
if (!modelData.onlyMenu) modelData.activate()
|
modelData.activate()
|
||||||
|
console.log('Activcate function of ', modelData.title)
|
||||||
|
}
|
||||||
if (modelData.title.trim()==="Steam") {
|
if (modelData.title.trim()==="Steam") {
|
||||||
console.log("[Tray] Starting Steam")
|
|
||||||
steamRunner.startDetached()
|
steamRunner.startDetached()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case Qt.RightButton:
|
|
||||||
console.log("[Tray] Context menu: " + modelData.title)
|
|
||||||
clickX = mouse.x
|
|
||||||
clickY = mouse.y
|
|
||||||
trayMenu.menu = modelData.menu
|
|
||||||
trayMenu.open()
|
|
||||||
break
|
|
||||||
case Qt.MiddleButton:
|
case Qt.MiddleButton:
|
||||||
console.log("[Tray] Secondary activate: " + modelData.title)
|
|
||||||
modelData.secondaryActivate()
|
modelData.secondaryActivate()
|
||||||
break
|
break
|
||||||
}
|
// case Qt.RightButton:
|
||||||
|
// if (modelData.hasMenu) {
|
||||||
|
// console.log('Activcate menu of ', modelData.title)
|
||||||
|
// menuAnchor.open()
|
||||||
|
// }
|
||||||
|
// break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QsMenuAnchor {
|
// QsMenuAnchor {
|
||||||
id: trayMenu
|
// id: menuAnchor
|
||||||
anchor {
|
// menu: modelData.menu
|
||||||
item: trayArea
|
// anchor.window: menuHost
|
||||||
edges: Edges.Top | Edges.Left
|
// }
|
||||||
gravity: Edges.Bottom | Edges.Right
|
|
||||||
adjustment: PopupAdjustment.FlipX | PopupAdjustment.SlideY
|
Rectangle {
|
||||||
onAnchoring: {
|
anchors.fill: parent
|
||||||
rect.x = trayArea.clickX
|
color: workspaceButton.containsMouse ? Colors.tertiaryContainer
|
||||||
rect.y = trayArea.clickY
|
: modelData.active ? Colors.primaryContainer
|
||||||
rect.w = 1
|
: Colors.secondaryContainer
|
||||||
rect.h = 1
|
border.color: workspaceButton.containsMouse ? Colors.tertiaryContainer_fg
|
||||||
}
|
: modelData.active ? Colors.primaryContainer_fg
|
||||||
|
: Colors.secondaryContainer_fg
|
||||||
|
radius: 6
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image { // Image
|
Image { // Image
|
||||||
id: iconImage
|
id: iconImage
|
||||||
|
source: modelData.icon
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: Config.halfBigIconSize(bar.height)
|
|
||||||
height: Config.halfBigIconSize(bar.height)
|
width: bar.height*0.75
|
||||||
|
height: bar.height*0.75
|
||||||
|
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
cache: true
|
cache: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
|
||||||
interval: Config.reload_interval
|
|
||||||
running: true
|
|
||||||
repeat: true
|
|
||||||
triggeredOnStart: true
|
|
||||||
onTriggered: {
|
|
||||||
let src = modelData.icon;
|
|
||||||
// console.log("########## icon: " + modelData.icon)
|
|
||||||
// console.log("########## name: " + modelData.title)
|
|
||||||
if (modelData.title.includes('GoXLR')) {
|
|
||||||
// console.log("[Tray] Resolving GoXLR icon path")
|
|
||||||
let pathMatch = src.match(/path=([^&]+)/);
|
|
||||||
if (pathMatch && pathMatch[1]) {
|
|
||||||
|
|
||||||
let folderPath = pathMatch[1];
|
|
||||||
let segments = folderPath.split('/');
|
|
||||||
let fileName = segments[segments.length - 1] + "-icon.png";
|
|
||||||
src = "file://" + pathMatch[1] + "/" + fileName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if (modelData.title.includes('Nextcloud')) {
|
|
||||||
// src = Quickshell.iconPath("Nextcloud")
|
|
||||||
// }
|
|
||||||
// console.log("########## icon: " + src)
|
|
||||||
if (src.exists) {
|
|
||||||
console.log("########## icon: " + src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the resolved source
|
|
||||||
iconImage.source = src;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import "../../../config"
|
|
||||||
import "../states/Apps"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property real pad: Config.spacing_fun(bar.height) * 1.5
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
|
|
||||||
implicitWidth: contentRow.implicitWidth + pad * 2
|
|
||||||
implicitHeight: contentRow.implicitHeight
|
|
||||||
|
|
||||||
readonly property string windowClass: Hyprland.activeToplevel?.wayland?.appId ?? ""
|
|
||||||
|
|
||||||
readonly property string windowTitle: {
|
|
||||||
const title = Hyprland.activeToplevel?.title;
|
|
||||||
if (!title)
|
|
||||||
return qsTr("Desktop");
|
|
||||||
return title.split(/\s+[\-\u2013\u2014\|]\s+/).pop();q
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property string appIcon: {
|
|
||||||
if (!root.windowClass) return AppsState.matchIcon(root.windowTitle);
|
|
||||||
|
|
||||||
let icon = AppsState.matchIcon(root.windowClass);
|
|
||||||
|
|
||||||
if (!icon) {
|
|
||||||
icon = AppsState.matchIcon(root.windowTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
|
|
||||||
id: contentRow
|
|
||||||
spacing: Config.spacing_fun(bar.height) * 1.25
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: root.windowTitle
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
elide: Text.ElideRight
|
|
||||||
maximumLineCount: 1
|
|
||||||
width: Math.min(implicitWidth, 250)
|
|
||||||
|
|
||||||
font.pixelSize: Config.iconSize(bar.height) * 0.8
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: root.appIcon
|
|
||||||
visible: text !== ""
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
font.pixelSize: Math.round(Config.iconSize(bar.height) * 0.85)
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,125 +1,62 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import "../../../config"
|
import "../../../colors"
|
||||||
import "../states/Apps"
|
|
||||||
|
|
||||||
Rectangle {
|
Row { // Workspace Row
|
||||||
id: workspacesContainer
|
|
||||||
required property HyprlandMonitor thisMonitor
|
|
||||||
|
|
||||||
height: bar.height - (Config.spacing_fun(bar.height) * 1.5)
|
|
||||||
width: workspacesRow.width + (Config.spacing_fun(bar.height) * 2)
|
|
||||||
|
|
||||||
radius: height / 2
|
|
||||||
|
|
||||||
color: Colors.surfaceVariant
|
|
||||||
border.color: Colors.surfaceVariant_fg
|
|
||||||
border.width: Config.border_width
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: workspacesRow
|
id: workspacesRow
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Config.spacing_fun(bar.height) / 2
|
|
||||||
|
|
||||||
Repeater {
|
required property HyprlandMonitor thisMonitor
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
Repeater { // repeats workspaces
|
||||||
model: Hyprland.workspaces
|
model: Hyprland.workspaces
|
||||||
Loader {
|
|
||||||
active: modelData.monitor === thisMonitor
|
|
||||||
sourceComponent: Item {
|
|
||||||
id: wsItem
|
|
||||||
property var workspaceData: modelData
|
|
||||||
|
|
||||||
width: Math.max(40, wsIconsRow.width==0 ? wsNum.width + 2*Config.spacing_fun(bar.height) : wsNum.width + wsIconsRow.width + 3*Config.spacing_fun(bar.height)+Config.spacing_fun(bar.height))
|
Rectangle { //workspace
|
||||||
// width: {
|
visible: modelData.monitor === thisMonitor
|
||||||
// var spacing = Config.spacing_fun(bar.height)
|
width: workspaceNum.width + 26
|
||||||
// var cw = wsNum.width
|
height: workspaceNum.height + 8
|
||||||
// if (wsIconsRow.children.length > 0) {
|
radius: 4
|
||||||
// cw += spacing + wsIconsRow.width + spacing
|
color: workspaceButton.containsMouse ? Colors.tertiaryContainer
|
||||||
// } else {
|
: modelData.active ? Colors.primaryContainer
|
||||||
// cw += spacing * 2
|
: Colors.secondaryContainer
|
||||||
// }
|
border.color: workspaceButton.containsMouse ? Colors.tertiaryContainer_fg
|
||||||
// Math.max(cw, wsNum.height + spacing * 2)
|
: modelData.active ? Colors.primaryContainer_fg
|
||||||
// }
|
: Colors.secondaryContainer_fg
|
||||||
height: workspacesContainer.height
|
border.width: 2
|
||||||
|
|
||||||
// highlight
|
|
||||||
Rectangle {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height - (Config.spacing_fun(bar.height) * 1.5)
|
|
||||||
|
|
||||||
radius: height / 2
|
|
||||||
|
|
||||||
color: wsArea.containsMouse ? Colors.tertiaryContainer
|
|
||||||
: workspaceData.active ? Colors.primaryContainer
|
|
||||||
: "transparent"
|
|
||||||
|
|
||||||
border.color: wsArea.containsMouse ? Colors.tertiaryContainer_fg
|
|
||||||
: workspaceData.active ? Colors.primaryContainer_fg
|
|
||||||
: "transparent"
|
|
||||||
|
|
||||||
border.width: (wsArea.containsMouse || workspaceData.active) ? Config.border_width : 0
|
|
||||||
|
|
||||||
// hyprland workspace api + color
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: wsArea
|
id: workspaceButton
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: Hyprland.dispatch("workspace " + modelData.id)
|
||||||
console.log("[Workspaces] Switch to workspace: " + workspaceData.id)
|
|
||||||
Hyprland.dispatch("workspace " + workspaceData.id)
|
|
||||||
Hyprland.dispatch("hl.dsp.focus({ workspace = "+workspaceData.id+" })")
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.fill: parent
|
||||||
anchors.leftMargin: wsIconsRow.width==0 ? (wsItem.width-wsNum.width)/2 : (wsItem.width-wsNum.width-wsIconsRow.width-Config.spacing_fun(bar.height))/2
|
color: "transparent"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
radius: 6
|
||||||
spacing: Config.spacing_fun(bar.height)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: wsNum
|
id: workspaceNum
|
||||||
text: workspaceData.id
|
text: modelData.id
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.centerIn: parent
|
||||||
color: wsArea.containsMouse ? Colors.tertiary
|
color: workspaceButton.containsMouse ? Colors.tertiary
|
||||||
: workspaceData.active ? Colors.primary
|
: modelData.active ? Colors.primary
|
||||||
: Colors.secondary
|
: Colors.secondary
|
||||||
font.pixelSize: Config.iconSize(bar.height)
|
font.pixelSize: 18
|
||||||
font.family: Config.font
|
font.family: "Inter, sans-serif"
|
||||||
font.bold: true
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
|
||||||
id: wsIconsRow
|
|
||||||
spacing: Config.spacing_fun(workspacesContainer.height)
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: AppsState.iconsForWorkspace(workspaceData.id)
|
|
||||||
delegate: Text {
|
|
||||||
text: modelData
|
|
||||||
color: wsArea.containsMouse ? Colors.tertiary
|
|
||||||
: Colors.secondary
|
|
||||||
font.pixelSize: Config.labelSize(bar.height)
|
|
||||||
font.family: Config.font
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
visible: Hyprland.workspaces.length === 0
|
visible: Hyprland.workspaces.length === 0
|
||||||
text: "No Workspaces"
|
text: "No Workspaces"
|
||||||
color: Colors.error
|
color: Colors.error
|
||||||
font.pixelSize: Config.iconSize(bar.height)
|
font.pixelSize: 18
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import QtQuick.Controls
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Io
|
|
||||||
import "../../config"
|
|
||||||
import "./modules"
|
|
||||||
|
|
||||||
PanelWindow {
|
|
||||||
id: learner
|
|
||||||
implicitWidth: screen.width * 0.75
|
|
||||||
implicitHeight: screen.height * 0.5
|
|
||||||
color: "transparent"
|
|
||||||
visible: true
|
|
||||||
focusable: true
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
semiJLoader.all_invisible()
|
|
||||||
semiJLoader.switchModeChooser()
|
|
||||||
}
|
|
||||||
|
|
||||||
FocusScope {
|
|
||||||
id: jLearnerScope
|
|
||||||
focus: true
|
|
||||||
|
|
||||||
Keys.onReleased: function(event) {
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
|
||||||
console.log("Pressed Escape, closing JLearner")
|
|
||||||
jLearnerLoader.active = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "lightblue"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: 10
|
|
||||||
color: Qt.alpha(Colors.surfaceContainerLowest, 0.5)
|
|
||||||
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.outlineVariant
|
|
||||||
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Rectangle{
|
|
||||||
width: parent.width - 20
|
|
||||||
height: parent.height - 20
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: learnerWindow
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: head
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height * 0.1
|
|
||||||
color: Colors.tertiaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.tertiaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "Language Learner"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: parent.height * 0.8
|
|
||||||
font.family: Config.font
|
|
||||||
color: Colors.tertiary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle{
|
|
||||||
id: semiJLoader
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height * 0.9 - parent.spacing
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
function all_invisible() {
|
|
||||||
languageChooser.visible = false
|
|
||||||
kanaVoicing.visible = false
|
|
||||||
voicingKana.visible = false
|
|
||||||
learnerResult.visible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchModeChooser() {
|
|
||||||
all_invisible()
|
|
||||||
languageChooser.visible = true
|
|
||||||
languageChooser.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
function switch_KanaVoicing() {
|
|
||||||
all_invisible()
|
|
||||||
kanaVoicing.visible = true
|
|
||||||
kanaVoicing.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
function switch_VoicingKana() {
|
|
||||||
all_invisible()
|
|
||||||
voicingKana.visible = true
|
|
||||||
voicingKana.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchResult(result, mode, results) {
|
|
||||||
all_invisible()
|
|
||||||
console.log("Result: " + result)
|
|
||||||
console.log("Mode: " + mode)
|
|
||||||
learnerResult.visible = true
|
|
||||||
learnerResult.result = result
|
|
||||||
learnerResult.mode = mode
|
|
||||||
learnerResult.results = results
|
|
||||||
learnerResult.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
ModeChooser {
|
|
||||||
id: languageChooser
|
|
||||||
}
|
|
||||||
|
|
||||||
KanaVoicing {
|
|
||||||
id: kanaVoicing
|
|
||||||
}
|
|
||||||
|
|
||||||
VoicingKana {
|
|
||||||
id: voicingKana
|
|
||||||
}
|
|
||||||
|
|
||||||
JLearnerResult {
|
|
||||||
id: learnerResult
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Io
|
|
||||||
|
|
||||||
|
|
||||||
Item { // container, invisible
|
|
||||||
id: jLoader
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: jLearnerLoader
|
|
||||||
active: false
|
|
||||||
sourceComponent: JLearner { id: jLearner }
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalShortcut {
|
|
||||||
name: "JLearner"
|
|
||||||
description: "Open Japanese Learner"
|
|
||||||
|
|
||||||
onPressed: {
|
|
||||||
console.log("Pressed Meta+Shift+J (Hyprland global shortcut)")
|
|
||||||
jLearnerLoader.active = !jLearnerLoader.active
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeJLearner() {
|
|
||||||
jLearnerLoader.active = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,300 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import "../../../config"
|
|
||||||
|
|
||||||
Item { // Chooser
|
|
||||||
id: learnerResult
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
anchors.margins: 15
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
function switch_KanaVoicing() {
|
|
||||||
parent.switch_KanaVoicing()
|
|
||||||
}
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
}
|
|
||||||
|
|
||||||
property real result: 0
|
|
||||||
property string mode: ""
|
|
||||||
property var results: createResults(10)
|
|
||||||
|
|
||||||
function createResults(n) {
|
|
||||||
var arr = []
|
|
||||||
for (var i = 0; i < n; i++) {
|
|
||||||
arr.push({
|
|
||||||
kana: "あ",
|
|
||||||
correctness: false,
|
|
||||||
answer: "a",
|
|
||||||
correct: "a"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return arr
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: learnerResultUpperText
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height * 0.1
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: mainText
|
|
||||||
text: "Ergebnisse:"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: parent.height * 0.6
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height - learnerResultUpperText.height - parent.spacing
|
|
||||||
spacing: 10
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width * 0.25
|
|
||||||
height: parent.height
|
|
||||||
color: "transparent"
|
|
||||||
Column{
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Repeater{
|
|
||||||
model: results
|
|
||||||
|
|
||||||
Row{
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height/10 - parent.spacing * 0.9
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Rectangle{
|
|
||||||
width: parent.height
|
|
||||||
height: parent.height
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text{
|
|
||||||
text: modelData.kana
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
anchors.centerIn: parent
|
|
||||||
anchors.verticalCenterOffset: -parent.height * 0.125
|
|
||||||
anchors.horizontalCenterOffset: parent.width * 0.1
|
|
||||||
font.pixelSize: parent.height * 0.8
|
|
||||||
font.family: Config.jfont
|
|
||||||
color: modelData.correctness ? "green" : "red"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle{
|
|
||||||
width: parent.height
|
|
||||||
height: parent.height
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Image {
|
|
||||||
source: modelData.correctness ? Config.configDir+"/modules/jl/assets/correct.svg" : Config.configDir+"/modules/jl/assets/wrong.svg"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: parent.height*0.8
|
|
||||||
height: parent.height*0.8
|
|
||||||
|
|
||||||
smooth: true
|
|
||||||
sourceSize.width: width
|
|
||||||
sourceSize.height: height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle{
|
|
||||||
width: parent.width - parent.height *2 - parent.spacing*2
|
|
||||||
height: parent.height
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text{
|
|
||||||
text: "[" + modelData.correct + "]"
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
anchors.centerIn: parent
|
|
||||||
anchors.horizontalCenterOffset: 10
|
|
||||||
font.pixelSize: parent.height * 0.8
|
|
||||||
font.family: Config.font
|
|
||||||
color: modelData.correctness ? "green" : "red"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle{
|
|
||||||
width: parent.width * 0.75
|
|
||||||
height: parent.height
|
|
||||||
color: "transparent"
|
|
||||||
Column{
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
spacing: 10
|
|
||||||
Row {
|
|
||||||
spacing: 10
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height * 4 / 10 - parent.spacing * 2 / 3
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
color: "transparent"
|
|
||||||
width: (parent.width - (learnerLastResultKanaBG.width + learnerLastResultTextBG.width))/2
|
|
||||||
height: parent.height
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: learnerLastResultKanaBG
|
|
||||||
color: results[results.length-1].correctness ? "green" : "red"
|
|
||||||
width: parent.height - parent.spacing
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: learnerLastResultKana
|
|
||||||
text: results[results.length-1].kana
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
anchors.centerIn: parent
|
|
||||||
anchors.verticalCenterOffset: -parent.height * 0.1
|
|
||||||
font.pixelSize: parent.height * 0.8
|
|
||||||
font.family: Config.font
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: learnerLastResultTextBG
|
|
||||||
color: results[results.length-1].correctness ? "green" : "red"
|
|
||||||
width: learnerLastResultText.width + 2 * parent.spacing
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: learnerLastResultText
|
|
||||||
text: "[" + results[results.length-1].correct + "]"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: learnerLastResultKana.font.pixelSize/2
|
|
||||||
font.family: Config.font
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: learnerResultTextBG
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height * 3 / 10 - parent.spacing * 2 / 3
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: learnerResultText
|
|
||||||
text: result*100 + "% Richtig"
|
|
||||||
width: parent.width
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.pixelSize: Math.min(parent.width / text.length * 1.2, parent.height * 0.8)
|
|
||||||
font.family: Config.font
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height * 3 / 10 - parent.spacing * 2 / 3
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
width: parent.width / 2 - parent.spacing
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
console.log("Choosing White Window")
|
|
||||||
mode === "KanaVoicing" ? learnerResult.parent.switch_KanaVoicing() : learnerResult.parent.switch_VoicingKana()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: parent.containsMouse ? Colors.secondaryContainer_fg : Colors.secondaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: parent.containsMouse ? Colors.secondaryContainer : Colors.secondaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "Again"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: Math.min(parent.width / text.length * 1.2, parent.height * 0.8)
|
|
||||||
font.family: Config.font
|
|
||||||
color: parent.parent.containsMouse ? Colors.secondary_fg : Colors.secondary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
width: parent.width / 2 - parent.spacing
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
console.log("Choosing Black Window")
|
|
||||||
learnerResult.parent.switchModeChooser()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: parent.containsMouse ? Colors.secondaryContainer_fg : Colors.secondaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: parent.containsMouse ? Colors.secondaryContainer : Colors.secondaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "Menu"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: Math.min(parent.width / text.length * 1.2, parent.height * 0.8)
|
|
||||||
font.family: Config.font
|
|
||||||
color: parent.parent.containsMouse ? Colors.secondary_fg : Colors.secondary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
property var kana: [
|
|
||||||
{ hira: "あ", voice: ["a"], known: true },
|
|
||||||
{ hira: "い", voice: ["i"], known: true },
|
|
||||||
{ hira: 'う', voice: ["u"], known: true },
|
|
||||||
{ hira: 'え', voice: ["e"], known: true },
|
|
||||||
{ hira: 'お', voice: ["o"], known: true },
|
|
||||||
{ hira: 'か', voice: ["ka"], known: true },
|
|
||||||
{ hira: 'が', voice: ["ga"], known: true },
|
|
||||||
{ hira: 'き', voice: ["ki"], known: true },
|
|
||||||
{ hira: 'ぎ', voice: ["gi"], known: true },
|
|
||||||
{ hira: 'く', voice: ["ku"], known: true },
|
|
||||||
{ hira: 'ぐ', voice: ["gu"], known: true },
|
|
||||||
{ hira: 'け', voice: ["ke"], known: true },
|
|
||||||
{ hira: 'げ', voice: ["ge"], known: true },
|
|
||||||
{ hira: 'こ', voice: ["ko"], known: true },
|
|
||||||
{ hira: 'ご', voice: ["go"], known: true },
|
|
||||||
{ hira: 'さ', voice: ["sa"], known: true },
|
|
||||||
{ hira: 'ざ', voice: ["za"], known: true },
|
|
||||||
{ hira: 'し', voice: ["si", "shi"], known: true },
|
|
||||||
{ hira: 'じ', voice: ["zi", "ji"], known: true },
|
|
||||||
{ hira: 'す', voice: ["su"], known: true },
|
|
||||||
{ hira: 'ず', voice: ["zu"], known: true },
|
|
||||||
{ hira: 'せ', voice: ["se"], known: true },
|
|
||||||
{ hira: 'ぜ', voice: ["ze"], known: true },
|
|
||||||
{ hira: 'そ', voice: ["so"], known: true },
|
|
||||||
{ hira: 'ぞ', voice: ["zo"], known: true },
|
|
||||||
{ hira: 'た', voice: ["ta"], known: true },
|
|
||||||
{ hira: 'だ', voice: ["da"], known: true },
|
|
||||||
{ hira: 'ち', voice: ["ti", "shi"], known: true },
|
|
||||||
{ hira: 'ぢ', voice: ["di", "ji"], known: true },
|
|
||||||
{ hira: 'つ', voice: ["tu", "tsu"], known: true },
|
|
||||||
{ hira: 'づ', voice: ["du", "zu"], known: true },
|
|
||||||
{ hira: 'て', voice: ["te"], known: true },
|
|
||||||
{ hira: 'で', voice: ["de"], known: true },
|
|
||||||
{ hira: 'と', voice: ["to"], known: true },
|
|
||||||
{ hira: 'ど', voice: ["do"], known: true },
|
|
||||||
{ hira: 'な', voice: ["na"], known: true },
|
|
||||||
{ hira: 'に', voice: ["ni"], known: true },
|
|
||||||
{ hira: 'ぬ', voice: ["nu"], known: false },
|
|
||||||
{ hira: 'ね', voice: ["ne"], known: false },
|
|
||||||
{ hira: 'の', voice: ["no"], known: false },
|
|
||||||
{ hira: 'は', voice: ["ha"], known: false },
|
|
||||||
{ hira: 'ば', voice: ["ba"], known: false },
|
|
||||||
{ hira: 'ぱ', voice: ["pa"], known: false },
|
|
||||||
{ hira: 'ひ', voice: ["hi"], known: false },
|
|
||||||
{ hira: 'び', voice: ["bi"], known: false },
|
|
||||||
{ hira: 'ぴ', voice: ["pi"], known: false },
|
|
||||||
{ hira: 'ふ', voice: ["hu"], known: false },
|
|
||||||
{ hira: 'ぶ', voice: ["bu"], known: false },
|
|
||||||
{ hira: 'ぷ', voice: ["pu"], known: false },
|
|
||||||
{ hira: 'へ', voice: ["he"], known: false },
|
|
||||||
{ hira: 'べ', voice: ["be"], known: false },
|
|
||||||
{ hira: 'ぺ', voice: ["pe"], known: false },
|
|
||||||
{ hira: 'ほ', voice: ["ho"], known: false },
|
|
||||||
{ hira: 'ぼ', voice: ["bo"], known: false },
|
|
||||||
{ hira: 'ぽ', voice: ["po"], known: false },
|
|
||||||
{ hira: 'ま', voice: ["ma"], known: false },
|
|
||||||
{ hira: 'み', voice: ["mi"], known: false },
|
|
||||||
{ hira: 'む', voice: ["mu"], known: false },
|
|
||||||
{ hira: 'め', voice: ["me"], known: false },
|
|
||||||
{ hira: 'も', voice: ["mo"], known: false },
|
|
||||||
{ hira: 'や', voice: ["ya"], known: false },
|
|
||||||
{ hira: 'ゆ', voice: ["yu"], known: false },
|
|
||||||
{ hira: 'よ', voice: ["yo"], known: false },
|
|
||||||
{ hira: 'ら', voice: ["ra"], known: false },
|
|
||||||
{ hira: 'り', voice: ["ri"], known: false },
|
|
||||||
{ hira: 'る', voice: ["ru"], known: false },
|
|
||||||
{ hira: 'れ', voice: ["re"], known: false },
|
|
||||||
{ hira: 'ろ', voice: ["ro"], known: false },
|
|
||||||
{ hira: 'わ', voice: ["wa"], known: false },
|
|
||||||
{ hira: 'ゐ', voice: ["wi"], known: false },
|
|
||||||
{ hira: 'ゑ', voice: ["we"], known: false },
|
|
||||||
{ hira: 'を', voice: ["wo"], known: false },
|
|
||||||
{ hira: 'ん', voice: ["n"], known: true },
|
|
||||||
{ hira: 'ゔ', voice: ["vu"], known: false }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import "../../../config"
|
|
||||||
|
|
||||||
Item { // Kana_Try
|
|
||||||
id: kanaVoicing
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
anchors.margins: 15
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
// Component.onCompleted: {
|
|
||||||
// randomKnownKana()
|
|
||||||
// }
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
kanaVoicingAnswer.focus = true
|
|
||||||
roundNum = 0
|
|
||||||
randomKnownKana()
|
|
||||||
}
|
|
||||||
|
|
||||||
KanaData {
|
|
||||||
id: kanaData
|
|
||||||
}
|
|
||||||
|
|
||||||
property var currentKana: []
|
|
||||||
|
|
||||||
property int roundNum: 0
|
|
||||||
property int correct: 0
|
|
||||||
property int maxRoundNum: 10
|
|
||||||
|
|
||||||
property var pastKana: []
|
|
||||||
property var pastCorrectness: []
|
|
||||||
|
|
||||||
function endRounds() {
|
|
||||||
kanaVoicingAnswer.focus = false
|
|
||||||
jLearnerScope.focus = true
|
|
||||||
console.log("Switching back")
|
|
||||||
parent.switchResult(correct/maxRoundNum, "KanaVoicing", pastCorrectness)
|
|
||||||
pastKana = []
|
|
||||||
pastCorrectness = []
|
|
||||||
correct = 0
|
|
||||||
kanaVoicingAnswer.placeholderText = "Type Voicing..."
|
|
||||||
kanaVoicingAnswerBackground.color = kanaVoicingAnswer.activeFocus ? Colors.tertiary_fg : Colors.primary_fg
|
|
||||||
}
|
|
||||||
|
|
||||||
function randomKana() {
|
|
||||||
if (roundNum >= maxRoundNum) {
|
|
||||||
endRounds()
|
|
||||||
}
|
|
||||||
var list = kanaData.kana
|
|
||||||
currentKana = list[Math.floor(Math.random() * list.length)]
|
|
||||||
if (knownList.length > maxRoundNum) {
|
|
||||||
while (pastKana.includes(currentKana)) {
|
|
||||||
currentKana = list[Math.floor(Math.random() * list.length)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pastKana.push(currentKana)
|
|
||||||
console.log("Round Num: " + roundNum + " - Choosing Kana: " + currentKana.hira)
|
|
||||||
roundNum = roundNum + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function randomKnownKana() {
|
|
||||||
if (roundNum >= maxRoundNum) {
|
|
||||||
endRounds()
|
|
||||||
}
|
|
||||||
var knownList = kanaData.kana.filter(k => k.known)
|
|
||||||
currentKana = knownList[Math.floor(Math.random() * knownList.length)]
|
|
||||||
if (knownList.length > maxRoundNum) {
|
|
||||||
while (pastKana.includes(currentKana)) {
|
|
||||||
currentKana = knownList[Math.floor(Math.random() * knownList.length)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pastKana.push(currentKana)
|
|
||||||
console.log("Round Num: " + roundNum + " - Choosing Kana: " + currentKana.hira)
|
|
||||||
roundNum = roundNum + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: kanaVoicingTextRectangale
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
width: kanaVoicingText.width + 20
|
|
||||||
height: parent.height * 0.1
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: kanaVoicingText
|
|
||||||
text: "Im Spiel - Runde: " + kanaVoicing.roundNum
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: parent.height * 0.6
|
|
||||||
font.family: Config.font
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: kanaVoicingKanaRectangle
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
height: (parent.height - kanaVoicingTextRectangale.height)*0.75
|
|
||||||
width: height
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: kanaVoicingKana
|
|
||||||
text: typeof kanaVoicing.currentKana.hira === "undefined" ? "" : kanaVoicing.currentKana.hira
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: Math.min(parent.width / text.length * 1.2, parent.height * 0.8)
|
|
||||||
font.family: Config.jfont
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: kanaVoicingAnswer
|
|
||||||
|
|
||||||
placeholderText: "Type Voicing..."
|
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
width: parent.width/2
|
|
||||||
height: (parent.height - kanaVoicingTextRectangale.height)*0.25 - parent.spacing*2
|
|
||||||
|
|
||||||
font.pixelSize: height * 0.8
|
|
||||||
|
|
||||||
color: Colors.secondary_fg
|
|
||||||
placeholderTextColor: Colors.secondary
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
id: kanaVoicingAnswerBackground
|
|
||||||
radius: 10
|
|
||||||
color: kanaVoicingAnswer.activeFocus ? Colors.secondaryContainer : Colors.secondaryContainer_fg
|
|
||||||
border.color: kanaVoicingAnswer.activeFocus ? Colors.secondaryContainer_fg : Colors.secondaryContainer
|
|
||||||
border.width: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onReleased: function(event) {
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
|
||||||
console.log("Escape pressed inside TextField")
|
|
||||||
console.log("Pressed Escape, closing JLearner")
|
|
||||||
jLearnerLoader.active = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccepted: function(event) {
|
|
||||||
console.log("Enter pressed inside TextField")
|
|
||||||
if (kanaVoicing.currentKana.voice.includes(kanaVoicingAnswer.text.toLowerCase())){
|
|
||||||
console.log("Correct")
|
|
||||||
kanaVoicingAnswer.text = ""
|
|
||||||
kanaVoicingAnswer.placeholderText = "[" + kanaVoicing.currentKana.voice + "]"
|
|
||||||
kanaVoicingAnswerBackground.color = "green"
|
|
||||||
kanaVoicing.correct = kanaVoicing.correct + 1
|
|
||||||
pastCorrectness.push({
|
|
||||||
kana: kanaVoicing.currentKana.hira,
|
|
||||||
correctness: true,
|
|
||||||
answer: kanaVoicingAnswer.text.toLowerCase(),
|
|
||||||
correct: kanaVoicing.currentKana.voice.join("|")
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
console.log("Wrong: [" + currentKana.voice + "]")
|
|
||||||
kanaVoicingAnswer.text = ""
|
|
||||||
kanaVoicingAnswerBackground.color = "red"
|
|
||||||
kanaVoicingAnswer.placeholderText = "[" + kanaVoicing.currentKana.voice + "]"
|
|
||||||
pastCorrectness.push({
|
|
||||||
kana: kanaVoicing.currentKana.hira,
|
|
||||||
correctness: false,
|
|
||||||
answer: kanaVoicingAnswer.text.toLowerCase(),
|
|
||||||
correct: kanaVoicing.currentKana.voice.join("|")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
randomKnownKana()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import "../../../config"
|
|
||||||
|
|
||||||
Item { // Chooser
|
|
||||||
id: languageChooser
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
anchors.margins: 15
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: modeChooserUpperText
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
width: mainText.width + 20
|
|
||||||
height: parent.height * 0.1
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: mainText
|
|
||||||
text: "Wähle ein Modus:"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: parent.height * 0.6
|
|
||||||
font.family: Config.font
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height - modeChooserUpperText.height - parent.spacing
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
width: (parent.width - parent.spacing) / 2
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
console.log("Choosing White Window")
|
|
||||||
languageChooser.parent.switch_KanaVoicing()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: parent.containsMouse ? Colors.secondaryContainer_fg : Colors.secondaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: parent.containsMouse ? Colors.secondaryContainer : Colors.secondaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "Kana to Voicing"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: Math.min(parent.width / text.length * 1.2, parent.height * 0.8)
|
|
||||||
font.family: Config.font
|
|
||||||
color: parent.parent.containsMouse ? Colors.secondary_fg : Colors.secondary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
width: (parent.width - parent.spacing) / 2
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
console.log("Choosing Black Window")
|
|
||||||
languageChooser.parent.switch_VoicingKana()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: parent.containsMouse ? Colors.secondaryContainer_fg : Colors.secondaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: parent.containsMouse ? Colors.secondaryContainer : Colors.secondaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "Voicing to Kana"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: Math.min(parent.width / text.length * 1.2, parent.height * 0.8)
|
|
||||||
font.family: Config.font
|
|
||||||
color: parent.parent.containsMouse ? Colors.secondary_fg : Colors.secondary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import "../../../config"
|
|
||||||
|
|
||||||
Item { // Kana_Try
|
|
||||||
id: voicingKana
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
anchors.margins: 15
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
// Component.onCompleted: {
|
|
||||||
// randomKnownKana()
|
|
||||||
// }
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
roundNum = 0
|
|
||||||
new_round()
|
|
||||||
}
|
|
||||||
|
|
||||||
KanaData {
|
|
||||||
id: kanaData
|
|
||||||
}
|
|
||||||
|
|
||||||
property int roundNum: 0
|
|
||||||
property int correct: 0
|
|
||||||
property int maxRoundNum: 10
|
|
||||||
|
|
||||||
property var pastKana: []
|
|
||||||
property var pastCorrectness: []
|
|
||||||
|
|
||||||
property var kanaArray: createResults(6)
|
|
||||||
property var targetKana: kanaArray[Math.floor(Math.random() * kanaArray.length)]
|
|
||||||
|
|
||||||
function createResults(n) {
|
|
||||||
var arr = []
|
|
||||||
for (var i = 0; i < n; i++) {
|
|
||||||
arr.push({ hira: "あ", voice: ["a"], known: true })
|
|
||||||
}
|
|
||||||
return arr
|
|
||||||
}
|
|
||||||
|
|
||||||
function new_round() {
|
|
||||||
roundNum = roundNum + 1
|
|
||||||
kanaArray = gemerateKanaArray()
|
|
||||||
targetKana = kanaArray[Math.floor(Math.random() * kanaArray.length)]
|
|
||||||
console.log("Round Num: " + roundNum + " - Choosing Kana: " + targetKana.hira)
|
|
||||||
pastKana.push(targetKana)
|
|
||||||
}
|
|
||||||
|
|
||||||
function gemerateKanaArray() {
|
|
||||||
var arr = []
|
|
||||||
for (var i = 0; i < 6; i++) {
|
|
||||||
arr.push(randomKnownKana(arr))
|
|
||||||
}
|
|
||||||
return arr
|
|
||||||
}
|
|
||||||
|
|
||||||
function randomKana(arr) {
|
|
||||||
if (roundNum > maxRoundNum) {
|
|
||||||
endRounds()
|
|
||||||
}
|
|
||||||
var list = kanaData.kana
|
|
||||||
var newKana = list[Math.floor(Math.random() * list.length)]
|
|
||||||
|
|
||||||
var arrExists = Array.isArray(arr)
|
|
||||||
|
|
||||||
if (knownList.length > maxRoundNum + 6) {
|
|
||||||
if (arrExists) {
|
|
||||||
while (pastKana.includes(newKana) || arr.includes(newKana)) {
|
|
||||||
newKana = list[Math.floor(Math.random() * list.length)]
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
while (pastKana.includes(newKana)){
|
|
||||||
newKana = list[Math.floor(Math.random() * list.length)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (arrExists) {
|
|
||||||
while (arr.includes(newKana)) {
|
|
||||||
newKana = list[Math.floor(Math.random() * list.length)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
kanaArray.push(newKana)
|
|
||||||
return newKana
|
|
||||||
}
|
|
||||||
|
|
||||||
function randomKnownKana(arr) {
|
|
||||||
if (roundNum > maxRoundNum) {
|
|
||||||
endRounds()
|
|
||||||
}
|
|
||||||
var knownList = kanaData.kana.filter(k => k.known)
|
|
||||||
var newKana = knownList[Math.floor(Math.random() * knownList.length)]
|
|
||||||
|
|
||||||
var arrExists = Array.isArray(arr)
|
|
||||||
|
|
||||||
if (knownList.length > maxRoundNum + 6) {
|
|
||||||
if (arrExists) {
|
|
||||||
while (pastKana.includes(newKana) || arr.includes(newKana)) {
|
|
||||||
newKana = knownList[Math.floor(Math.random() * knownList.length)]
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
while (pastKana.includes(newKana)){
|
|
||||||
newKana = knownList[Math.floor(Math.random() * knownList.length)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (arrExists) {
|
|
||||||
while (arr.includes(newKana)) {
|
|
||||||
newKana = knownList[Math.floor(Math.random() * knownList.length)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newKana
|
|
||||||
}
|
|
||||||
|
|
||||||
function endRounds() {
|
|
||||||
console.log("Switching back")
|
|
||||||
roundNum = 0
|
|
||||||
parent.switchResult(correct/maxRoundNum, "VoicingKana", pastCorrectness)
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: voicingKanaTextRectangale
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
width: mainText.width + 20
|
|
||||||
height: parent.height * 0.1
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: mainText
|
|
||||||
text: "Runde: " + roundNum + " - [" + targetKana.voice.join("|") + "]:"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: parent.height * 0.6
|
|
||||||
font.family: Config.font
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle{
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height - voicingKanaTextRectangale.height - voicingKanaResultRectangale.height - parent.spacing * 2
|
|
||||||
color: "transparent"
|
|
||||||
Grid {
|
|
||||||
id: grid
|
|
||||||
anchors.fill: parent
|
|
||||||
columns: 3
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
property int rows: 2
|
|
||||||
|
|
||||||
// calculate cell width and height based on parent size, spacing, and number of columns/rows
|
|
||||||
property real cellWidth: (width - (columns - 1) * spacing) / columns
|
|
||||||
property real cellHeight: (height - (rows - 1) * spacing) / rows
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: kanaArray
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
width: grid.cellWidth
|
|
||||||
height: grid.cellHeight
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
console.log("Choose a Kana: " + modelData.hira)
|
|
||||||
if (modelData.hira === targetKana.hira) {
|
|
||||||
console.log("Correct")
|
|
||||||
correct = correct + 1
|
|
||||||
voicingKanaResultRectangale.color = "green"
|
|
||||||
} else {
|
|
||||||
console.log("Wrong: [" + targetKana.hira + "]")
|
|
||||||
voicingKanaResultRectangale.color = "red"
|
|
||||||
}
|
|
||||||
pastCorrectness.push({
|
|
||||||
kana: targetKana.hira,
|
|
||||||
correctness: modelData.hira === targetKana.hira,
|
|
||||||
answer: modelData.hira,
|
|
||||||
correct: targetKana.voice.join("|")
|
|
||||||
})
|
|
||||||
voicingKanaResult.text = "Letzte Runde: " + targetKana.hira + ": " + "[" + targetKana.voice.join("|") + "]"
|
|
||||||
new_round()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
color: parent.containsMouse ? Colors.secondaryContainer_fg : Colors.secondaryContainer
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: parent.containsMouse ? Colors.secondaryContainer : Colors.secondaryContainer_fg
|
|
||||||
|
|
||||||
Text{
|
|
||||||
text: modelData.hira
|
|
||||||
anchors.centerIn: parent
|
|
||||||
anchors.verticalCenterOffset: -parent.height * 0.1
|
|
||||||
font.pixelSize: parent.height * 0.8
|
|
||||||
font.family: Config.jfont
|
|
||||||
color: parent.parent.containsMouse ? Colors.secondary_fg : Colors.secondary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: voicingKanaResultRectangale
|
|
||||||
color: Colors.primaryContainer
|
|
||||||
width: voicingKanaResult.width + 20
|
|
||||||
height: parent.height * 0.1
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
border.width: 2
|
|
||||||
border.color: Colors.primaryContainer_fg
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: voicingKanaResult
|
|
||||||
text: "Wähle das richtige Zeichen"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pixelSize: parent.height * 0.6
|
|
||||||
font.family: Config.font
|
|
||||||
color: Colors.primary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell.Io
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
required property string command
|
|
||||||
required property string text
|
|
||||||
required property string icon
|
|
||||||
required property string icon_text
|
|
||||||
property var keybind: null
|
|
||||||
|
|
||||||
id: button
|
|
||||||
|
|
||||||
readonly property var process: Process {
|
|
||||||
command: ["sh", "-c", button.command]
|
|
||||||
}
|
|
||||||
|
|
||||||
function exec() {
|
|
||||||
process.startDetached();
|
|
||||||
console.log("Picked Logout Option, closing WLogout");
|
|
||||||
wlogoutLoader.active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
import Quickshell.Wayland
|
|
||||||
|
|
||||||
import "../../config"
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
id: root
|
|
||||||
property color buttonColor: Colors.secondaryContainer
|
|
||||||
property color buttonHoverColor: Colors.primary
|
|
||||||
property color borderColor: Colors.secondaryContainer_fg
|
|
||||||
property color borderHoverColor: Colors.primaryContainer_fg
|
|
||||||
default property list<LogoutButton> buttons
|
|
||||||
|
|
||||||
model: Quickshell.screens
|
|
||||||
PanelWindow {
|
|
||||||
id: w
|
|
||||||
|
|
||||||
property var modelData
|
|
||||||
screen: modelData
|
|
||||||
|
|
||||||
exclusionMode: ExclusionMode.Ignore
|
|
||||||
WlrLayershell.layer: WlrLayer.Overlay
|
|
||||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
contentItem {
|
|
||||||
focus: true
|
|
||||||
Keys.onPressed: event => {
|
|
||||||
if (event.key == Qt.Key_Escape) {
|
|
||||||
console.log("Pressed Escape, closing Wallpaper Picker")
|
|
||||||
console.log("Wallpaper Dir:", Config.wallpaperDir)
|
|
||||||
wlogoutLoader.active = false
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < buttons.length; i++) {
|
|
||||||
let button = buttons[i];
|
|
||||||
if (event.key == button.keybind) button.exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
left: true
|
|
||||||
bottom: true
|
|
||||||
right: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.fill: parent
|
|
||||||
source: Config.wallpaperDir + "/Static/blurred.jpg"
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
console.log("clicked ???, closing Wallpaper Picker")
|
|
||||||
wlogoutLoader.active = false
|
|
||||||
}
|
|
||||||
GridLayout {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
width: parent.width * 0.75
|
|
||||||
height: parent.height * 0.75
|
|
||||||
|
|
||||||
columns: 3
|
|
||||||
columnSpacing: 20
|
|
||||||
rowSpacing: 20
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: buttons
|
|
||||||
delegate: Rectangle {
|
|
||||||
required property LogoutButton modelData;
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
color: ma.containsMouse ? buttonHoverColor : buttonColor
|
|
||||||
radius: 10
|
|
||||||
border.color: ma.containsMouse ? borderColor : borderHoverColor
|
|
||||||
border.width: 2
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: ma
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: modelData.exec()
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: icon
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: `icons/${modelData.icon}.svg`
|
|
||||||
width: parent.width * 0.3
|
|
||||||
height: parent.width * 0.3
|
|
||||||
|
|
||||||
sourceSize.width: width
|
|
||||||
sourceSize.height: height
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text {
|
|
||||||
// id: icon
|
|
||||||
// anchors.centerIn: parent
|
|
||||||
|
|
||||||
// text: modelData.icon_text ?? "?"
|
|
||||||
// font.pointSize: parent.height * 0.4
|
|
||||||
// color: "white"
|
|
||||||
// }
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors {
|
|
||||||
top: icon.bottom
|
|
||||||
topMargin: 20
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
text: modelData.text
|
|
||||||
font.pointSize: 20
|
|
||||||
color: "white"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import "../../config"
|
|
||||||
|
|
||||||
ShellRoot {
|
|
||||||
WLogout {
|
|
||||||
LogoutButton {
|
|
||||||
command: Config.configDir + "/modules/wlogout/scripts/lock.sh"
|
|
||||||
keybind: Qt.Key_L
|
|
||||||
text: "Lock"
|
|
||||||
icon: "lock"
|
|
||||||
icon_text: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
LogoutButton {
|
|
||||||
command: Config.configDir + "/modules/wlogout/scripts/logout.sh"
|
|
||||||
keybind: Qt.Key_E
|
|
||||||
text: "Logout"
|
|
||||||
icon: "logout"
|
|
||||||
icon_text: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
LogoutButton {
|
|
||||||
command: Config.configDir + "/modules/wlogout/scripts/suspend.sh"
|
|
||||||
keybind: Qt.Key_U
|
|
||||||
text: "Suspend"
|
|
||||||
icon: "suspend"
|
|
||||||
icon_text: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
LogoutButton {
|
|
||||||
command: Config.configDir + "/modules/wlogout/scripts/hibernate.sh"
|
|
||||||
keybind: Qt.Key_H
|
|
||||||
text: "Hibernate"
|
|
||||||
icon: "hibernate"
|
|
||||||
icon_text: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
LogoutButton {
|
|
||||||
command: Config.configDir + "/modules/wlogout/scripts/shutdown.sh"
|
|
||||||
keybind: Qt.Key_K
|
|
||||||
text: "Shutdown"
|
|
||||||
icon: "shutdown"
|
|
||||||
icon_text: "⏻"
|
|
||||||
}
|
|
||||||
|
|
||||||
LogoutButton {
|
|
||||||
command: Config.configDir + "/modules/wlogout/scripts/reboot.sh"
|
|
||||||
keybind: Qt.Key_R
|
|
||||||
text: "Reboot"
|
|
||||||
icon: "reboot"
|
|
||||||
icon_text: " "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Io
|
|
||||||
import "../../config"
|
|
||||||
|
|
||||||
|
|
||||||
Item { // container, invisible
|
|
||||||
id: wlLoader
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: wlogoutLoader
|
|
||||||
active: false
|
|
||||||
sourceComponent: Wlogout {
|
|
||||||
id: wLogout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalShortcut {
|
|
||||||
name: "WLogout"
|
|
||||||
description: "Open WLogout"
|
|
||||||
|
|
||||||
onPressed: {
|
|
||||||
console.log("Pressed Meta+Shift+W (Hyprland global shortcut)")
|
|
||||||
wlogoutLoader.active = !wlogoutLoader.active
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function openWlogout() {
|
|
||||||
wlogoutLoader.active = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeWlogout() {
|
|
||||||
wlogoutLoader.active = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
systemctl hibernate
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
hyprlock
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 1. Run helper script if it exists
|
|
||||||
if [[ -x "$SCRIPT_PATH" ]]; then
|
|
||||||
echo "Running helper script..."
|
|
||||||
bash "$SCRIPT_PATH"
|
|
||||||
else
|
|
||||||
echo "Helper script not found, skipping..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Run hyprshutdown if available
|
|
||||||
if command -v hyprshutdown >/dev/null 2>&1; then
|
|
||||||
echo "Running hyprshutdown..."
|
|
||||||
hyprshutdown
|
|
||||||
else
|
|
||||||
echo "Rebooting system..."
|
|
||||||
if command -v systemctl >/dev/null 2>&1; then
|
|
||||||
systemctl loginctl terminate-user $USER
|
|
||||||
else
|
|
||||||
pkill -KILL -u "$USER" -t tty2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
SCRIPT_PATH="$HOME/.config/quickshell/modules/wlogout/scripts/helper.sh"
|
|
||||||
|
|
||||||
# 1. Run helper script if it exists
|
|
||||||
if [[ -x "$SCRIPT_PATH" ]]; then
|
|
||||||
echo "Running helper script..."
|
|
||||||
bash "$SCRIPT_PATH"
|
|
||||||
else
|
|
||||||
echo "Helper script not found, skipping..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Run hyprshutdown if available
|
|
||||||
if command -v hyprshutdown >/dev/null 2>&1; then
|
|
||||||
echo "Running hyprshutdown..."
|
|
||||||
hyprshutdown
|
|
||||||
else
|
|
||||||
echo "hyprshutdown not found, skipping..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Power off if systemctl exists
|
|
||||||
if command -v systemctl >/dev/null 2>&1; then
|
|
||||||
echo "Rebooting system..."
|
|
||||||
systemctl reboot
|
|
||||||
else
|
|
||||||
reboot
|
|
||||||
fi
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
SCRIPT_PATH="$HOME/.config/quickshell/modules/wlogout/scripts/helper.sh"
|
|
||||||
|
|
||||||
# 1. Run helper script if it exists
|
|
||||||
if [[ -x "$SCRIPT_PATH" ]]; then
|
|
||||||
echo "Running helper script..."
|
|
||||||
bash "$SCRIPT_PATH"
|
|
||||||
else
|
|
||||||
echo "Helper script not found, skipping..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Run hyprshutdown if available
|
|
||||||
if command -v hyprshutdown >/dev/null 2>&1; then
|
|
||||||
echo "Running hyprshutdown..."
|
|
||||||
hyprshutdown
|
|
||||||
else
|
|
||||||
echo "hyprshutdown not found, skipping..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Power off if systemctl exists
|
|
||||||
if command -v systemctl >/dev/null 2>&1; then
|
|
||||||
echo "Powering off system..."
|
|
||||||
systemctl poweroff
|
|
||||||
else
|
|
||||||
shutdown -h now
|
|
||||||
fi
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
systemctl suspend
|
|
||||||
@@ -4,7 +4,7 @@ import QtQuick.Controls
|
|||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Qt.labs.folderlistmodel
|
import Qt.labs.folderlistmodel
|
||||||
import "../../config"
|
import "../../colors"
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: picker
|
id: picker
|
||||||
@@ -14,23 +14,6 @@ PanelWindow {
|
|||||||
visible: true
|
visible: true
|
||||||
focusable: true
|
focusable: true
|
||||||
|
|
||||||
FocusScope {
|
|
||||||
id: pickerScope
|
|
||||||
focus: true
|
|
||||||
|
|
||||||
Keys.onReleased: function(event) {
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
|
||||||
console.log("Pressed Escape, closing Wallpaper Picker")
|
|
||||||
wallpaperLoader.active = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "lightblue"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: 10
|
radius: 10
|
||||||
@@ -59,22 +42,11 @@ PanelWindow {
|
|||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
|
|
||||||
radius: 12
|
radius: 12
|
||||||
color: filterText.activeFocus ? Colors.tertiary_fg : Colors.primary_fg
|
color: "#2b2b2b"
|
||||||
border.color: filterText.activeFocus ? Colors.tertiary : Colors.primary
|
border.color: filterText.activeFocus ? "#4da3ff" : "#555"
|
||||||
border.width: 1
|
border.width: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onReleased: {
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
|
||||||
console.log("Escape pressed inside TextField")
|
|
||||||
console.log("Pressed Escape, closing Wallpaper Picker")
|
|
||||||
// wallpaperLoader.active = false
|
|
||||||
filterText.text = ""
|
|
||||||
filterText.focus = false
|
|
||||||
event.accepted = true
|
|
||||||
pickerScope.focus = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -88,7 +60,7 @@ PanelWindow {
|
|||||||
|
|
||||||
width: parent.width - 35
|
width: parent.width - 35
|
||||||
height: parent.height - 100
|
height: parent.height - 100
|
||||||
color: Colors.surfaceContainer
|
color: Qt.alpha(Colors.surfaceContainer, 0.5)
|
||||||
radius: 10
|
radius: 10
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
@@ -143,30 +115,20 @@ PanelWindow {
|
|||||||
|
|
||||||
|
|
||||||
// pictures + text
|
// pictures + text
|
||||||
delegate: Rectangle {
|
delegate: Item {
|
||||||
width: grid.cellWidth -10
|
width: grid.cellWidth
|
||||||
height: grid.cellHeight -25
|
height: grid.cellHeight
|
||||||
color: mouseArea.containsMouse ? Qt.alpha(Colors.surfaceContainerHover, 0.5) : "transparent" // select color
|
|
||||||
radius: 10
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
spacing: 20
|
spacing: 20
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: grid.cellWidth -10
|
|
||||||
height: grid.cellHeight * 0.7
|
|
||||||
|
|
||||||
border.width: 2
|
|
||||||
border.color: mouseArea.containsMouse ? Qt.alpha(Colors.surfaceContainerHover, 0.5) : "transparent"
|
|
||||||
|
|
||||||
radius: 10
|
|
||||||
|
|
||||||
Image { // Image
|
Image { // Image
|
||||||
source: filePath
|
source: filePath
|
||||||
anchors.fill: parent
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
|
width: grid.cellWidth -10
|
||||||
|
height: grid.cellHeight * 0.7
|
||||||
|
|
||||||
sourceSize.width: grid.cellWidth -10
|
sourceSize.width: grid.cellWidth -10
|
||||||
sourceSize.height: grid.cellHeight * 0.7
|
sourceSize.height: grid.cellHeight * 0.7
|
||||||
|
|
||||||
@@ -174,14 +136,6 @@ PanelWindow {
|
|||||||
cache: true
|
cache: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "transparent"
|
|
||||||
border.width: 2
|
|
||||||
border.color: mouseArea.containsMouse ? Qt.alpha(Colors.surfaceContainerHover, 0.5) : "transparent"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle { // highlight of text
|
Rectangle { // highlight of text
|
||||||
id: textHighlight
|
id: textHighlight
|
||||||
width: parent.width - 10
|
width: parent.width - 10
|
||||||
@@ -205,7 +159,7 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Process {
|
Process {
|
||||||
id: wallpaperProcess
|
id: wallpaperProcess
|
||||||
command: ["sh", "-c", Config.configDir + "/modules/wp/set-wallpaper.sh" + " " + model.filePath + " &"]
|
command: ["sh", "-c", Quickshell.env("HOME") + "/.config/quickshell/modules/wp/set-wallpaper.sh" + " " + model.filePath + " &"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: console.log('line read:', this.text)
|
onStreamFinished: console.log('line read:', this.text)
|
||||||
}
|
}
|
||||||
@@ -237,7 +191,7 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: 10
|
radius: 10
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: Colors.primary
|
border.color: Colors.outline
|
||||||
border.width: 1
|
border.width: 1
|
||||||
z: 999
|
z: 999
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,14 @@ import QtQuick
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import "../../config"
|
|
||||||
|
|
||||||
|
|
||||||
Item {
|
Item { // container, invisible
|
||||||
id: wLoader
|
id: wLoader
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: generateThumbs
|
id: generateThumbs
|
||||||
command: ["sh", "-c", Config.configDir + "/modules/wp/generate-wallpaper-thumbs.sh"]
|
command: ["sh", "-c", Quickshell.env("HOME") + "/.config/quickshell/modules/wp/generate-wallpaper-thumbs.sh"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: console.log(this.text)
|
onStreamFinished: console.log(this.text)
|
||||||
}
|
}
|
||||||
@@ -29,8 +28,8 @@ Item {
|
|||||||
onPressed: {
|
onPressed: {
|
||||||
// generateThumbs.startDetached()
|
// generateThumbs.startDetached()
|
||||||
generateThumbs.running = true
|
generateThumbs.running = true
|
||||||
console.log("Pressed Meta+Shift+W (Hyprland global shortcut)")
|
|
||||||
wallpaperLoader.active = !wallpaperLoader.active
|
wallpaperLoader.active = !wallpaperLoader.active
|
||||||
|
console.log("Pressed Meta+Shift+W (Hyprland global shortcut)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,16 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
|
||||||
|
|
||||||
# Folder with full-size wallpapers
|
# Folder with full-size wallpapers
|
||||||
WALLPAPER_DIR=$("$SCRIPT_DIR/../../scripts/wallpaper_dir.sh")
|
WALLPAPER_DIR="$HOME/Pictures/Wallpapers"
|
||||||
|
|
||||||
echo "$WALLPAPER_DIR"
|
|
||||||
|
|
||||||
# Folder to store thumbnails
|
# Folder to store thumbnails
|
||||||
THUMB_DIR="$HOME/.cache/wallpaper-thumbs"
|
THUMB_DIR="$HOME/.cache/wallpaper-thumbs"
|
||||||
echo "$THUMB_DIR"
|
|
||||||
|
|
||||||
if [ ! -d $THUMB_DIR ]; then
|
if [ ! -d $THUMB_DIR ]; then
|
||||||
mkdir -p $THUMB_DIR;
|
mkdir -p $THUMB_DIR;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
shopt -s nullglob
|
|
||||||
files=( "$THUMB_DIR"/*.jpg "$THUMB_DIR"/*.jpeg "$THUMB_DIR"/*.png )
|
|
||||||
# printf ' %s\n' "${files[@]}"
|
|
||||||
# Make sure the thumb directory exists
|
# Make sure the thumb directory exists
|
||||||
mkdir -p "$THUMB_DIR"
|
mkdir -p "$THUMB_DIR"
|
||||||
|
|
||||||
@@ -26,28 +19,6 @@ MAX_DIM=300
|
|||||||
|
|
||||||
num=0
|
num=0
|
||||||
|
|
||||||
remove_from_array() {
|
|
||||||
local -n arr=$1
|
|
||||||
local elem=$2
|
|
||||||
local result=()
|
|
||||||
|
|
||||||
# echo "=== Removing element: '$elem' ==="
|
|
||||||
# echo "Original array has ${#arr[@]} elements"
|
|
||||||
|
|
||||||
for item in "${arr[@]}"; do
|
|
||||||
if [[ "$item" != "$elem" ]]; then
|
|
||||||
result+=( "$item" )
|
|
||||||
# echo "Keeping: '$item'"
|
|
||||||
# else
|
|
||||||
# echo "Removing: '$item'"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
arr=( "${result[@]}" )
|
|
||||||
# echo "New array has ${#arr[@]} elements"
|
|
||||||
# echo "-----------------------------------"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Process each image
|
# Process each image
|
||||||
for img in "$WALLPAPER_DIR"/*.{jpg,jpeg,png}; do
|
for img in "$WALLPAPER_DIR"/*.{jpg,jpeg,png}; do
|
||||||
# Skip if no files match
|
# Skip if no files match
|
||||||
@@ -55,46 +26,19 @@ for img in "$WALLPAPER_DIR"/*.{jpg,jpeg,png}; do
|
|||||||
|
|
||||||
# Get just the filename
|
# Get just the filename
|
||||||
fname=$(basename "$img")
|
fname=$(basename "$img")
|
||||||
name="${fname%.*}"
|
|
||||||
ext="${fname##*.}"
|
|
||||||
|
|
||||||
# no magick file:
|
|
||||||
temp_image_name="$THUMB_DIR/${name}_tmp.${ext}"
|
|
||||||
|
|
||||||
# Output path
|
# Output path
|
||||||
thumb="$THUMB_DIR/$fname"
|
thumb="$THUMB_DIR/$fname"
|
||||||
|
|
||||||
|
|
||||||
# If thumbnail already exists and is newer than the original, skip
|
# If thumbnail already exists and is newer than the original, skip
|
||||||
if [ -f "$thumb" ] && [ "$thumb" -nt "$img" ]; then
|
if [ -f "$thumb" ] && [ "$thumb" -nt "$img" ]; then
|
||||||
remove_from_array files "$thumb"
|
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
((num++))
|
num+=1
|
||||||
|
|
||||||
# Generate thumbnail using ImageMagick
|
# Generate thumbnail using ImageMagick
|
||||||
if [ -x "/usr/bin/magick" ]; then
|
|
||||||
magick "$img" -resize "${MAX_DIM}x${MAX_DIM}" "$thumb"
|
magick "$img" -resize "${MAX_DIM}x${MAX_DIM}" "$thumb"
|
||||||
if [ -f "$temp_image_name" ]; then
|
|
||||||
rm "$temp_image_name"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ -f "$temp_image_name" ] && [ "$temp_image_name" -nt "$img" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
cp $img $temp_image_name
|
|
||||||
fi
|
|
||||||
remove_from_array files "$thumb"
|
|
||||||
done
|
|
||||||
|
|
||||||
# echo ""
|
|
||||||
|
|
||||||
# printf ' %s\n' "${files[@]}"
|
|
||||||
|
|
||||||
for img in $files; do
|
|
||||||
# echo "$img"
|
|
||||||
rm $img
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "$num Thumbnails generated in $THUMB_DIR"
|
echo "$num Thumbnails generated in $THUMB_DIR"
|
||||||
@@ -1,18 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
|
||||||
|
|
||||||
# Folder with full-size wallpapers
|
|
||||||
WALLPAPER_DIR=$("$SCRIPT_DIR/../../scripts/wallpaper_dir.sh")
|
|
||||||
if [ -z "$WALLPAPER_DIR" ]; then
|
|
||||||
echo "Failed to determine wallpaper directory. Exiting."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Path to the image is the first argument
|
# Path to the image is the first argument
|
||||||
IMAGE="$1"
|
IMAGE="$1"
|
||||||
image_name=$(basename "$IMAGE")
|
image_name=$(basename "$IMAGE")
|
||||||
image="$WALLPAPER_DIR/$image_name"
|
image="$HOME/Pictures/Wallpapers/$image_name"
|
||||||
|
|
||||||
|
echo "start"
|
||||||
|
|
||||||
# Check if an image was provided
|
# Check if an image was provided
|
||||||
if [[ -z "$IMAGE" ]]; then
|
if [[ -z "$IMAGE" ]]; then
|
||||||
@@ -20,7 +13,6 @@ if [[ -z "$IMAGE" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "start"
|
|
||||||
|
|
||||||
if [ -x "/usr/bin/swww-daemon" ]; then
|
if [ -x "/usr/bin/swww-daemon" ]; then
|
||||||
echo "swww-daemon exists and is executable"
|
echo "swww-daemon exists and is executable"
|
||||||
@@ -50,25 +42,14 @@ elif [ -x "/usr/bin/hyprpaper" ]; then
|
|||||||
sleep 0.2
|
sleep 0.2
|
||||||
echo "daemon started"
|
echo "daemon started"
|
||||||
fi
|
fi
|
||||||
sed -i "3s|path = .*|path = ${image}|" ~/.config/hypr/hyprpaper.conf
|
hyprctl hyprpaper wallpaper ", $image"
|
||||||
|
|
||||||
hyprctl monitors -j | jq -r 'sort_by(.id) | .[].name' | while IFS= read -r display; do
|
|
||||||
# echo "hyprctl hyprpaper wallpaper $display, $image"
|
|
||||||
hyprctl hyprpaper wallpaper "$display, $image"
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -x "/usr/bin/matugen" ]; then
|
matugen image $image --mode dark
|
||||||
echo "matugen exists, creating colors"
|
|
||||||
matugen image $image --mode dark --source-color-index 0
|
|
||||||
echo "matugen image $image --mode dark --source-color-index 0"
|
|
||||||
else
|
|
||||||
cp "$SCRIPT_DIR/../../assets/example_colors.qml" "$SCRIPT_DIR/../../config/Colors.qml"
|
|
||||||
fi
|
|
||||||
|
|
||||||
### Blured Wallpaper for wlogout
|
### Blured Wallpaper for wlogout
|
||||||
blur="50x30"
|
blur="50x30"
|
||||||
static_wallpaper_dir="$WALLPAPER_DIR/Static"
|
static_wallpaper_dir="$HOME/Pictures/Wallpapers/Static"
|
||||||
|
|
||||||
if [ ! -d $static_wallpaper_dir ]; then
|
if [ ! -d $static_wallpaper_dir ]; then
|
||||||
mkdir -p $static_wallpaper_dir;
|
mkdir -p $static_wallpaper_dir;
|
||||||
@@ -80,15 +61,6 @@ echo "$image" > $current_wallpaper
|
|||||||
|
|
||||||
blurred_wp="$static_wallpaper_dir/blurred.jpg"
|
blurred_wp="$static_wallpaper_dir/blurred.jpg"
|
||||||
|
|
||||||
if command -v magick >/dev/null 2>&1; then
|
|
||||||
magick $image -blur $blur $blurred_wp
|
magick $image -blur $blur $blurred_wp
|
||||||
# echo "magick $image -blur $blur $blurred_wp"
|
|
||||||
else
|
|
||||||
cp $image $blurred_wp
|
|
||||||
fi
|
|
||||||
# if [ -x "/usr/bin/sddm" ] && [ -d "/usr/share/backgrounds" ]; then
|
|
||||||
# sddm_background="/usr/share/backgrounds/background.jpg"
|
|
||||||
# cp "$image" "$sddm_background"
|
|
||||||
# fi
|
|
||||||
|
|
||||||
echo "test"
|
echo "test"
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Setting wallpaper_dir
|
|
||||||
|
|
||||||
WALLPAPER_DIR="${XDG_PICTURES_DIR:-}"
|
|
||||||
|
|
||||||
# 2. If empty, use xdg-user-dir (most reliable)
|
|
||||||
if [ -z "$WALLPAPER_DIR" ]; then
|
|
||||||
if command -v xdg-user-dir >/dev/null 2>&1; then
|
|
||||||
WALLPAPER_DIR="$(xdg-user-dir PICTURES 2>/dev/null)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Final fallback (hardcoded default)
|
|
||||||
if [ -z "$WALLPAPER_DIR" ] || [ ! -d "$WALLPAPER_DIR" ]; then
|
|
||||||
WALLPAPER_DIR="$HOME/Pictures"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. Your wallpaper subfolder
|
|
||||||
WALLPAPER_DIR="$WALLPAPER_DIR/Wallpapers"
|
|
||||||
|
|
||||||
echo $WALLPAPER_DIR
|
|
||||||
@@ -5,9 +5,6 @@ import Quickshell.Hyprland
|
|||||||
import QtQuick //for Text
|
import QtQuick //for Text
|
||||||
import "./modules/bar"
|
import "./modules/bar"
|
||||||
import "./modules/wp"
|
import "./modules/wp"
|
||||||
import "./modules/wlogout"
|
|
||||||
import "./modules/jl"
|
|
||||||
import "./modules/background"
|
|
||||||
|
|
||||||
ShellRoot {
|
ShellRoot {
|
||||||
id: root
|
id: root
|
||||||
@@ -18,17 +15,4 @@ ShellRoot {
|
|||||||
//Wallpaper picker
|
//Wallpaper picker
|
||||||
WallpaperPickerLoader {}
|
WallpaperPickerLoader {}
|
||||||
|
|
||||||
//Japanese Lerner
|
|
||||||
JLearnerLoader {}
|
|
||||||
|
|
||||||
//Wlogout
|
|
||||||
WlogoutLoader {
|
|
||||||
id : wlLoader
|
|
||||||
}
|
|
||||||
|
|
||||||
Background {}
|
|
||||||
|
|
||||||
function openWlogout() {
|
|
||||||
wlLoader.openWlogout()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user