Merge branch 'main' of github.com:Teoro01/hyprland-quickshell-gui
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
# HyprlandQuickshellGUI: a replacement for Waybar
|
||||||
|
|
||||||
|
## 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```
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 14 MiB |
@@ -0,0 +1,57 @@
|
|||||||
|
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"
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15.928 4.59635C15.656 4.59154 15.3937 4.6962 15.2018 4.88607L14.7443 5.33897L14.7532 5.3477L10.6335 9.40399C10.3409 9.69209 10.3409 10.1592 10.6335 10.4472L12.8293 12.6093C13.1219 12.8974 13.5962 12.8974 13.8888 12.6093L18.0198 8.54183L18.0206 8.54261L20.7408 5.93893C21.2184 5.48177 20.898 4.68415 20.232 4.6724L15.928 4.59635Z" fill="url(#paint0_linear_451_3032)"/>
|
||||||
|
<path d="M6.07245 9.17448C6.34442 9.16967 6.6067 9.27425 6.79855 9.4642L7.25611 9.91706L7.24725 9.92579L11.3669 13.9821C11.6595 14.2702 11.6595 14.7373 11.3669 15.0254L9.17115 17.1873C8.87858 17.4754 8.40417 17.4754 8.11157 17.1873L3.98062 13.1199L3.9798 13.1207L1.25963 10.5171C0.782021 10.0599 1.10244 9.26227 1.7684 9.25053L6.07245 9.17448Z" fill="url(#paint1_linear_451_3032)"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_451_3032" x1="13.3523" y1="13.0948" x2="3.69727" y2="3.70258" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#2AD454"/>
|
||||||
|
<stop offset="1" stop-color="#B3FF5A"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_451_3032" x1="13.3518" y1="13.0948" x2="3.69684" y2="3.70247" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#2AD454"/>
|
||||||
|
<stop offset="1" stop-color="#B3FF5A"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,24 @@
|
|||||||
|
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_451_2160)">
|
||||||
|
<path d="M20.2812 11C20.2812 5.87599 16.124 1.71875 11 1.71875C5.87599 1.71875 1.71875 5.87599 1.71875 11C1.71875 16.124 5.87599 20.2812 11 20.2812C16.124 20.2812 20.2812 16.124 20.2812 11Z" stroke="url(#paint0_linear_451_2160)" stroke-width="2.6" stroke-miterlimit="10"/>
|
||||||
|
<path d="M14.0938 14.0938L7.90625 7.90625" stroke="url(#paint1_linear_451_2160)" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M7.90625 14.0938L14.0938 7.90625" stroke="url(#paint2_linear_451_2160)" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_451_2160" x1="20.2263" y1="1.83639" x2="1.81064" y2="20.0988" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FE7970"/>
|
||||||
|
<stop offset="1" stop-color="#DC3282"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_451_2160" x1="14.0754" y1="7.94547" x2="7.93688" y2="14.0329" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FE7970"/>
|
||||||
|
<stop offset="1" stop-color="#DC3282"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint2_linear_451_2160" x1="14.0754" y1="7.94547" x2="7.93688" y2="14.0329" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FE7970"/>
|
||||||
|
<stop offset="1" stop-color="#DC3282"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip0_451_2160">
|
||||||
|
<rect width="22" height="22" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -77,8 +77,5 @@ PanelWindow {
|
|||||||
PowerButton {}
|
PowerButton {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Somewhere add Tray
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+127
@@ -0,0 +1,127 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ID="$1"
|
||||||
|
|
||||||
|
if [[ -z "$ID" ]]; then
|
||||||
|
echo "Usage: $0 Number"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# 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"]=""
|
||||||
|
["LibreWolf"]=""
|
||||||
|
["midori"]=""
|
||||||
|
["brave-browser"]=""
|
||||||
|
["chromium"]=""
|
||||||
|
# E-Mail
|
||||||
|
["org.mozilla.Thunderbird"]=""
|
||||||
|
# Terminals
|
||||||
|
["kitty"]=""
|
||||||
|
["Alacritty"]=""
|
||||||
|
# Videoplayer
|
||||||
|
["VLC media player"]=""
|
||||||
|
["mpv"]=""
|
||||||
|
["ffplay"]=""
|
||||||
|
# Chats
|
||||||
|
["discord"]=""
|
||||||
|
["vesktop"]=""
|
||||||
|
["Signal"]=""
|
||||||
|
["xyz.chatboxapp.app"]=""
|
||||||
|
# Coding
|
||||||
|
["Visual Studio Code"]=""
|
||||||
|
["VSCodium"]=""
|
||||||
|
["jetbrains-idea"]=""
|
||||||
|
["jetbrains-studio"]=""
|
||||||
|
# Text Editor
|
||||||
|
["mousepad"]=""
|
||||||
|
# Password
|
||||||
|
["org.keepassxc.KeePassXC"]=""
|
||||||
|
["Yubico Authenticator"]=""
|
||||||
|
# Cloud
|
||||||
|
["com.nextcloud.desktopclient.nextcloud"]=""
|
||||||
|
# App Store
|
||||||
|
["Octopi"]=""
|
||||||
|
# Games
|
||||||
|
["steam"]=""
|
||||||
|
["org.prismlauncher.PrismLauncher"]=""
|
||||||
|
["Minecraft* 1.21.11"]=""
|
||||||
|
["game"]=""
|
||||||
|
# Digital Arts
|
||||||
|
["Blender"]=""
|
||||||
|
["Krita"]=""
|
||||||
|
# VM
|
||||||
|
["virt-manager"]=""
|
||||||
|
["VirtualBox Manager"]=""
|
||||||
|
["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"]=""
|
||||||
|
["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"]=""
|
||||||
|
)
|
||||||
|
|
||||||
|
# APPS=$(hyprctl clients -j | jq -r ".[] | select(.workspace.id == $ID) | .initialTitle")
|
||||||
|
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
for i in "${!APPS[@]}"; do
|
||||||
|
if [[ -n "${MAP["${APPS[$i]}"]}" ]]; then
|
||||||
|
APPS[$i]="${MAP["${APPS[$i]}"]}"
|
||||||
|
elif [[ -n "${MAP["${APPS_CLASS[$i]}"]}" ]]; then
|
||||||
|
APPS[$i]="${MAP["${APPS_CLASS[$i]}"]}"
|
||||||
|
else
|
||||||
|
APPS[$i]="${APPS_CLASS[$i]}|${APPS[$i]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# for app in "${APPS[@]}"; do
|
||||||
|
# echo "$app"
|
||||||
|
# done
|
||||||
|
|
||||||
|
RESULT="$ID $(printf '%s ' "${APPS[@]}")"
|
||||||
|
RESULT=${RESULT% } # remove trailing space
|
||||||
|
echo "$RESULT"
|
||||||
@@ -4,34 +4,73 @@ import Quickshell.Hyprland
|
|||||||
import "../../../colors"
|
import "../../../colors"
|
||||||
|
|
||||||
Rectangle { //workspace
|
Rectangle { //workspace
|
||||||
width: timeDisplay.width + 16
|
width: timeDisplay.width + 8 + dateDisplay.width + 16
|
||||||
height: timeDisplay.height + 16
|
height: timeDisplay.height + 16
|
||||||
radius: 4
|
radius: 4
|
||||||
color: Colors.primaryContainer
|
color: Colors.primaryContainer
|
||||||
border.color: Colors.primaryContainer_fg
|
border.color: Colors.primaryContainer_fg
|
||||||
border.width: 2
|
border.width: 2
|
||||||
|
MouseArea {
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||||
|
|
||||||
Text {
|
Row {
|
||||||
id: timeDisplay
|
id: row
|
||||||
|
spacing: 8
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
property string currentTime: ""
|
Text {
|
||||||
|
id: dateDisplay
|
||||||
|
property string currentDate: ""
|
||||||
|
|
||||||
text: currentTime
|
text: currentDate
|
||||||
color: Colors.primary
|
color: Colors.primary
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.family: "Inter, sans-serif"
|
font.family: "Inter, sans-serif"
|
||||||
|
|
||||||
anchors.centerIn: parent
|
Timer {
|
||||||
|
id: dateTimer
|
||||||
//Update time every second
|
interval: 60000
|
||||||
Timer {
|
running: false
|
||||||
interval: 1000
|
repeat: true
|
||||||
running: true
|
triggeredOnStart: true
|
||||||
repeat: true
|
onTriggered: {
|
||||||
onTriggered: {
|
var now = new Date()
|
||||||
var now = new Date()
|
dateDisplay.currentDate = Qt.formatDate(now, "dd.MM.yyyy")
|
||||||
timeDisplay.currentTime = Qt.formatTime(now, "hh:mm:ss")
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: timeDisplay
|
||||||
|
property string currentTime: ""
|
||||||
|
|
||||||
|
text: currentTime
|
||||||
|
color: Colors.primary
|
||||||
|
font.pixelSize: 18
|
||||||
|
font.family: "Inter, sans-serif"
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var now = new Date()
|
||||||
|
currentTime = Qt.formatTime(now, "hh:mm:ss")
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 1000
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
var now = new Date()
|
||||||
|
timeDisplay.currentTime = Qt.formatTime(now, "hh:mm:ss")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
dateDisplay.currentDate = "";
|
||||||
|
dateTimer.running = !dateTimer.running;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ import "../../../colors"
|
|||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: networkButton
|
id: networkButton
|
||||||
width: output.width + 16
|
width: bar.height
|
||||||
height: bar.height
|
height: bar.height
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -19,7 +19,9 @@ MouseArea {
|
|||||||
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: 6
|
radius: 6
|
||||||
width: output.width + 16
|
border.width: 2
|
||||||
|
border.color: networkButton.containsMouse ? Colors.tertiaryContainer_fg
|
||||||
|
: Colors.secondaryContainer_fg
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: output
|
id: output
|
||||||
@@ -37,7 +39,7 @@ MouseArea {
|
|||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
output.text = this.text.trim()
|
output.text = this.text.trim()
|
||||||
console.log("networkScript output:", this.text.trim())
|
// console.log("networkScript output:", this.text.trim())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+130
-70
@@ -7,85 +7,145 @@ import "../../../colors"
|
|||||||
|
|
||||||
Row { // Workspace Row
|
Row { // Workspace Row
|
||||||
id: trayRow
|
id: trayRow
|
||||||
spacing: 8
|
spacing: 4
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: SystemTray.items
|
model: SystemTray.items
|
||||||
|
Column{
|
||||||
Rectangle { //trayItem
|
Rectangle{
|
||||||
id: trayItem
|
width: iconImage.width + 8
|
||||||
width: bar.height
|
height: (bar.height-trayItem.height)/2
|
||||||
height: bar.height
|
color: "transparent"
|
||||||
radius: 4
|
|
||||||
color: "transparent"
|
|
||||||
border.width: 2
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: steamRunner
|
|
||||||
command: ["steam", "steam://open/main"]
|
|
||||||
running: false
|
|
||||||
}
|
}
|
||||||
|
Rectangle { //trayItem
|
||||||
|
id: trayItem
|
||||||
|
width: iconImage.width + 8
|
||||||
|
height: iconImage.height + 8
|
||||||
|
radius: 4
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 2
|
||||||
|
|
||||||
MouseArea {
|
Process {
|
||||||
id: workspaceButton
|
id: steamRunner
|
||||||
hoverEnabled: true
|
command: ["steam", "steam://open/main"]
|
||||||
cursorShape: Qt.PointingHandCursor
|
running: false
|
||||||
anchors.fill: parent
|
}
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
|
||||||
onClicked: (mouse) => {
|
MouseArea {
|
||||||
switch (mouse.button) {
|
id: workspaceButton
|
||||||
case Qt.LeftButton:
|
hoverEnabled: true
|
||||||
if (!modelData.onlyMenu) {
|
cursorShape: Qt.PointingHandCursor
|
||||||
modelData.activate()
|
anchors.fill: parent
|
||||||
console.log('Activcate function of ', modelData.title)
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||||
|
onClicked: (mouse) => {
|
||||||
|
switch (mouse.button) {
|
||||||
|
case Qt.LeftButton:
|
||||||
|
if (!modelData.onlyMenu) {
|
||||||
|
modelData.activate()
|
||||||
|
console.log('Activcate function of ', modelData.title)
|
||||||
|
}
|
||||||
|
if (modelData.title.trim()==="Steam") {
|
||||||
|
steamRunner.startDetached()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case Qt.MiddleButton:
|
||||||
|
modelData.secondaryActivate()
|
||||||
|
break
|
||||||
|
// case Qt.RightButton:
|
||||||
|
// if (modelData.hasMenu) {
|
||||||
|
// console.log('Activcate menu of ', modelData.title)
|
||||||
|
// menuAnchor.open()
|
||||||
|
// }
|
||||||
|
// break
|
||||||
}
|
}
|
||||||
if (modelData.title.trim()==="Steam") {
|
}
|
||||||
steamRunner.startDetached()
|
|
||||||
}
|
// QsMenuAnchor {
|
||||||
break
|
// id: menuAnchor
|
||||||
case Qt.MiddleButton:
|
// menu: modelData.menu
|
||||||
modelData.secondaryActivate()
|
// anchor.window: menuHost
|
||||||
break
|
// }
|
||||||
// case Qt.RightButton:
|
|
||||||
// if (modelData.hasMenu) {
|
Rectangle {
|
||||||
// console.log('Activcate menu of ', modelData.title)
|
anchors.fill: parent
|
||||||
// menuAnchor.open()
|
color: workspaceButton.containsMouse ? Colors.tertiaryContainer
|
||||||
|
: modelData.active ? Colors.primaryContainer
|
||||||
|
: Colors.secondaryContainer
|
||||||
|
border.color: workspaceButton.containsMouse ? Colors.tertiaryContainer_fg
|
||||||
|
: modelData.active ? Colors.primaryContainer_fg
|
||||||
|
: Colors.secondaryContainer_fg
|
||||||
|
radius: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Image { // Image
|
||||||
|
id: iconImage
|
||||||
|
// source: modelData.icon; Does not work for some tray icons
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
width: bar.height*0.5
|
||||||
|
height: bar.height*0.5
|
||||||
|
|
||||||
|
// Component.onCompleted: {
|
||||||
|
// // Default to the original icon
|
||||||
|
// let src = modelData.icon;
|
||||||
|
// // console.log("########## icon: " + modelData.icon)
|
||||||
|
|
||||||
|
// // Check if there is a "?" in the URL (custom path)
|
||||||
|
// if (src.includes('goxlr')) {
|
||||||
|
// let pathMatch = src.match(/path=([^&]+)/);
|
||||||
|
// if (pathMatch && pathMatch[1]) {
|
||||||
|
|
||||||
|
// let folderPath = pathMatch[1];
|
||||||
|
// // Build a file:// URL pointing to the actual icon file
|
||||||
|
// let segments = folderPath.split('/');
|
||||||
|
// let fileName = segments[segments.length - 1] + "-icon.png";
|
||||||
|
// console.log("########## filename: " + fileName)
|
||||||
|
// console.log("########## icon: " + modelData.icon)
|
||||||
|
// src = "file://" + pathMatch[1] + "/" + fileName;
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
// break
|
|
||||||
|
// // Set the resolved source
|
||||||
|
// iconImage.source = src;
|
||||||
|
|
||||||
|
// // console.log("Resolved icon source:", src);
|
||||||
|
// }
|
||||||
|
asynchronous: true
|
||||||
|
cache: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 10000
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
triggeredOnStart: true
|
||||||
|
onTriggered: {
|
||||||
|
let src = modelData.icon;
|
||||||
|
// console.log("########## icon: " + modelData.icon)
|
||||||
|
|
||||||
|
// Check if there is a "?" in the URL (custom path)
|
||||||
|
if (src.includes('goxlr')) {
|
||||||
|
let pathMatch = src.match(/path=([^&]+)/);
|
||||||
|
if (pathMatch && pathMatch[1]) {
|
||||||
|
|
||||||
|
let folderPath = pathMatch[1];
|
||||||
|
// Build a file:// URL pointing to the actual icon file
|
||||||
|
let segments = folderPath.split('/');
|
||||||
|
let fileName = segments[segments.length - 1] + "-icon.png";
|
||||||
|
// console.log("########## filename: " + fileName)
|
||||||
|
// console.log("########## icon: " + modelData.icon)
|
||||||
|
src = "file://" + pathMatch[1] + "/" + fileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the resolved source
|
||||||
|
iconImage.source = src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// QsMenuAnchor {
|
|
||||||
// id: menuAnchor
|
|
||||||
// menu: modelData.menu
|
|
||||||
// anchor.window: menuHost
|
|
||||||
// }
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: workspaceButton.containsMouse ? Colors.tertiaryContainer
|
|
||||||
: modelData.active ? Colors.primaryContainer
|
|
||||||
: Colors.secondaryContainer
|
|
||||||
border.color: workspaceButton.containsMouse ? Colors.tertiaryContainer_fg
|
|
||||||
: modelData.active ? Colors.primaryContainer_fg
|
|
||||||
: Colors.secondaryContainer_fg
|
|
||||||
radius: 6
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Image { // Image
|
|
||||||
id: iconImage
|
|
||||||
source: modelData.icon
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
width: bar.height*0.75
|
|
||||||
height: bar.height*0.75
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
cache: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Io
|
||||||
import "../../../colors"
|
import "../../../colors"
|
||||||
|
|
||||||
Row { // Workspace Row
|
Row { // Workspace Row
|
||||||
@@ -9,48 +10,84 @@ Row { // Workspace Row
|
|||||||
required property HyprlandMonitor thisMonitor
|
required property HyprlandMonitor thisMonitor
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
|
// Get infos of Type Unknown
|
||||||
|
// Repeater {
|
||||||
|
// model: Hyprland.workspaces
|
||||||
|
|
||||||
|
// Rectangle {
|
||||||
|
// Component.onCompleted: {
|
||||||
|
// console.log("roles:")
|
||||||
|
// console.log("id:", modelData.id)
|
||||||
|
// console.log("monitor:", modelData.monitor)
|
||||||
|
// console.log("monitorId:", modelData.monitorId)
|
||||||
|
// console.log("name:", modelData.name)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
Repeater { // repeats workspaces
|
Repeater { // repeats workspaces
|
||||||
model: Hyprland.workspaces
|
model: Hyprland.workspaces
|
||||||
|
Loader {
|
||||||
|
active: modelData.monitor === thisMonitor
|
||||||
|
sourceComponent: Rectangle { //workspace
|
||||||
|
// visible: modelData.monitor === thisMonitor
|
||||||
|
width: (workspaceNum.width + 16) < (workspaceNum.height + 8) ? workspaceNum.height + 8 : workspaceNum.width + 16
|
||||||
|
height: workspaceNum.height + 8
|
||||||
|
radius: 4
|
||||||
|
color: workspaceButton.containsMouse ? Colors.tertiaryContainer
|
||||||
|
: modelData.active ? Colors.primaryContainer
|
||||||
|
: Colors.secondaryContainer
|
||||||
|
border.color: workspaceButton.containsMouse ? Colors.tertiaryContainer_fg
|
||||||
|
: modelData.active ? Colors.primaryContainer_fg
|
||||||
|
: Colors.secondaryContainer_fg
|
||||||
|
border.width: 2
|
||||||
|
|
||||||
Rectangle { //workspace
|
MouseArea {
|
||||||
visible: modelData.monitor === thisMonitor
|
id: workspaceButton
|
||||||
width: workspaceNum.width + 26
|
hoverEnabled: true
|
||||||
height: workspaceNum.height + 8
|
cursorShape: Qt.PointingHandCursor
|
||||||
radius: 4
|
|
||||||
color: workspaceButton.containsMouse ? Colors.tertiaryContainer
|
|
||||||
: modelData.active ? Colors.primaryContainer
|
|
||||||
: Colors.secondaryContainer
|
|
||||||
border.color: workspaceButton.containsMouse ? Colors.tertiaryContainer_fg
|
|
||||||
: modelData.active ? Colors.primaryContainer_fg
|
|
||||||
: Colors.secondaryContainer_fg
|
|
||||||
border.width: 2
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: workspaceButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: Hyprland.dispatch("workspace " + modelData.id)
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "transparent"
|
onClicked: Hyprland.dispatch("workspace " + modelData.id)
|
||||||
radius: 6
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
radius: 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: workspaceNum
|
||||||
|
text: modelData.id
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: workspaceButton.containsMouse ? Colors.tertiary
|
||||||
|
: modelData.active ? Colors.primary
|
||||||
|
: Colors.secondary
|
||||||
|
font.pixelSize: 18
|
||||||
|
font.family: "Inter, sans-serif"
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: workspaceContent
|
||||||
|
command: ["sh", "-c", Quickshell.env("HOME") + "/.config/quickshell/modules/bar/scripts/Apps.sh " + modelData.id]
|
||||||
|
running: true
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
workspaceNum.text = this.text
|
||||||
|
// console.log("workspaceScript output:", this.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 1000
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: workspaceContent.running = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
|
||||||
id: workspaceNum
|
|
||||||
text: modelData.id
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: workspaceButton.containsMouse ? Colors.tertiary
|
|
||||||
: modelData.active ? Colors.primary
|
|
||||||
: Colors.secondary
|
|
||||||
font.pixelSize: 18
|
|
||||||
font.family: "Inter, sans-serif"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Io
|
||||||
|
import "../../colors"
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import "../../../colors"
|
||||||
|
|
||||||
|
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
|
||||||
|
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 ? "../../../colors/icons/correct.svg" : "../../../colors/icons/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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
color: parent.parent.containsMouse ? Colors.secondary_fg : Colors.secondary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
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 }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import "../../../colors"
|
||||||
|
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import "../../../colors"
|
||||||
|
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
color: parent.parent.containsMouse ? Colors.secondary_fg : Colors.secondary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import "../../../colors"
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
color: Colors.primary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,23 @@ 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
|
||||||
@@ -42,11 +59,22 @@ PanelWindow {
|
|||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
|
|
||||||
radius: 12
|
radius: 12
|
||||||
color: "#2b2b2b"
|
color: filterText.activeFocus ? Colors.tertiary_fg : Colors.primary_fg
|
||||||
border.color: filterText.activeFocus ? Colors.tertiary : Colors.primary
|
border.color: filterText.activeFocus ? Colors.tertiary : Colors.primary
|
||||||
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ Item { // container, invisible
|
|||||||
onPressed: {
|
onPressed: {
|
||||||
// generateThumbs.startDetached()
|
// generateThumbs.startDetached()
|
||||||
generateThumbs.running = true
|
generateThumbs.running = true
|
||||||
wallpaperLoader.active = !wallpaperLoader.active
|
|
||||||
console.log("Pressed Meta+Shift+W (Hyprland global shortcut)")
|
console.log("Pressed Meta+Shift+W (Hyprland global shortcut)")
|
||||||
|
wallpaperLoader.active = !wallpaperLoader.active
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ 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"
|
||||||
|
|
||||||
@@ -19,6 +21,28 @@ 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
|
||||||
@@ -26,19 +50,44 @@ 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+=1
|
num+=1
|
||||||
|
|
||||||
# Generate thumbnail using ImageMagick
|
# Generate thumbnail using ImageMagick
|
||||||
magick "$img" -resize "${MAX_DIM}x${MAX_DIM}" "$thumb"
|
if [ -x "/usr/bin/magick" ]; then
|
||||||
|
magick "$img" -resize "${MAX_DIM}x${MAX_DIM}" "$thumb"
|
||||||
|
rm $temp_image_name
|
||||||
|
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"
|
||||||
@@ -42,10 +42,15 @@ 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 hyprpaper wallpaper ", $image"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
matugen image $image --mode dark
|
if [ -x "/usr/bin/matugen" ]; then
|
||||||
|
matugen image $image --mode dark
|
||||||
|
else
|
||||||
|
cp $HOME/.config/quickshell/colors/example_colors.qml $HOME/.config/quickshell/colors/Colors.qml
|
||||||
|
fi
|
||||||
|
|
||||||
### Blured Wallpaper for wlogout
|
### Blured Wallpaper for wlogout
|
||||||
blur="50x30"
|
blur="50x30"
|
||||||
@@ -61,6 +66,14 @@ echo "$image" > $current_wallpaper
|
|||||||
|
|
||||||
blurred_wp="$static_wallpaper_dir/blurred.jpg"
|
blurred_wp="$static_wallpaper_dir/blurred.jpg"
|
||||||
|
|
||||||
magick $image -blur $blur $blurred_wp
|
if [ -x "/usr/bin/sddm" ]; then
|
||||||
|
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"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ 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/japanese"
|
||||||
|
|
||||||
ShellRoot {
|
ShellRoot {
|
||||||
id: root
|
id: root
|
||||||
@@ -15,4 +16,7 @@ ShellRoot {
|
|||||||
//Wallpaper picker
|
//Wallpaper picker
|
||||||
WallpaperPickerLoader {}
|
WallpaperPickerLoader {}
|
||||||
|
|
||||||
|
//Japanese Lerner
|
||||||
|
JLearnerLoader {}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user