moved files
This commit is contained in:
223
arch/.config/nlogout/src/nlogout.nim
Normal file
223
arch/.config/nlogout/src/nlogout.nim
Normal file
@@ -0,0 +1,223 @@
|
||||
import std/[os, osproc, tables, strutils]
|
||||
import nlogout_config
|
||||
import nigui
|
||||
|
||||
|
||||
proc getDesktopEnvironment(): string =
|
||||
let xdgCurrentDesktop = getEnv("XDG_CURRENT_DESKTOP").toLower()
|
||||
if xdgCurrentDesktop != "":
|
||||
return xdgCurrentDesktop
|
||||
|
||||
let desktopSession = getEnv("DESKTOP_SESSION").toLower()
|
||||
if desktopSession != "":
|
||||
return desktopSession
|
||||
|
||||
return "unknown"
|
||||
|
||||
proc terminate(sApp: string) =
|
||||
discard execCmd("pkill " & sApp)
|
||||
|
||||
proc getIconPath(config: Config, buttonKey: string): string =
|
||||
result = ICON_THEME_PATH / config.iconTheme / (buttonKey & ".svg")
|
||||
if not fileExists(result):
|
||||
result = ICON_THEME_PATH / "default" / (buttonKey & ".svg")
|
||||
|
||||
proc hexToRgb(hex: string): Color =
|
||||
var hexColor = hex.strip()
|
||||
if hexColor.startsWith("#"):
|
||||
hexColor = hexColor[1..^1]
|
||||
if hexColor.len == 6:
|
||||
let
|
||||
r = byte(parseHexInt(hexColor[0..1]))
|
||||
g = byte(parseHexInt(hexColor[2..3]))
|
||||
b = byte(parseHexInt(hexColor[4..5]))
|
||||
result = rgb(r, g, b)
|
||||
else:
|
||||
result = rgb(0.byte, 0.byte, 0.byte)
|
||||
|
||||
###############################################################################
|
||||
proc drawRoundedRect(canvas: Canvas, x, y, width, height, radius: float, color: Color) =
|
||||
# Set the fill and line color
|
||||
canvas.areaColor = color
|
||||
canvas.lineColor = color
|
||||
|
||||
let radiusInt = radius.int
|
||||
|
||||
# Draw the main rectangle
|
||||
canvas.drawRectArea(x.int + radiusInt, y.int, (width - radius * 2).int, height.int)
|
||||
canvas.drawRectArea(x.int, y.int + radiusInt, width.int, (height - radius * 2).int)
|
||||
|
||||
|
||||
# Draw the rounded corners using arcs
|
||||
canvas.drawArcOutline(x.int + radiusInt, y.int + radiusInt, radius, 180, 90) # Top-left
|
||||
canvas.drawArcOutline((x + width).int - radiusInt, y.int + radiusInt, radius, 270, 90) # Top-right
|
||||
canvas.drawArcOutline(x.int + radiusInt, (y + height).int - radiusInt, radius, 90, 90) # Bottom-left
|
||||
canvas.drawArcOutline((x + width).int - radiusInt, (y + height).int - radiusInt, radius, 0, 90) # Bottom-right
|
||||
|
||||
|
||||
# Fill the corners
|
||||
canvas.drawEllipseArea(x.int, y.int, radiusInt * 2, radiusInt * 2) # Top-left
|
||||
canvas.drawEllipseArea((x + width).int - radiusInt * 2, y.int, radiusInt * 2, radiusInt * 2) # Top-right
|
||||
canvas.drawEllipseArea(x.int, (y + height).int - radiusInt * 2, radiusInt * 2, radiusInt * 2) # Bottom-left
|
||||
canvas.drawEllipseArea((x + width).int - radiusInt * 2, (y + height).int - radiusInt * 2, radiusInt * 2, radiusInt * 2) # Bottom-right
|
||||
|
||||
|
||||
|
||||
|
||||
proc createButton(cfg: ButtonConfig, config: Config, buttonKey: string, action: proc()): Control =
|
||||
var button = newControl()
|
||||
button.width = config.buttonWidth
|
||||
button.height = config.buttonHeight
|
||||
|
||||
button.onDraw = proc(event: DrawEvent) =
|
||||
let canvas = event.control.canvas
|
||||
let buttonWidth = button.width.float
|
||||
let buttonHeight = button.height.float
|
||||
|
||||
if config.cornerRadius > 0:
|
||||
drawRoundedRect(canvas, 0, 0, buttonWidth, buttonHeight, config.cornerRadius.float, hexToRgb(cfg.backgroundColor))
|
||||
else:
|
||||
canvas.areaColor = hexToRgb(cfg.backgroundColor)
|
||||
canvas.drawRectArea(0, 0, buttonWidth.int, buttonHeight.int)
|
||||
|
||||
canvas.fontFamily = config.fontFamily
|
||||
canvas.fontSize = config.fontSize.float
|
||||
canvas.fontBold = config.fontBold
|
||||
canvas.textColor = hexToRgb(cfg.textColor)
|
||||
|
||||
var y = config.buttonTopPadding.float
|
||||
|
||||
# Draw icon
|
||||
let iconPath = getIconPath(config, buttonKey)
|
||||
if fileExists(iconPath):
|
||||
var icon = newImage()
|
||||
icon.loadFromFile(iconPath)
|
||||
let iconX = (buttonWidth - config.iconSize.float) / 2
|
||||
let iconY = y
|
||||
canvas.drawImage(icon, iconX.int, iconY.int, config.iconSize, config.iconSize)
|
||||
y += config.iconSize.float + 5 # Add some padding after the icon
|
||||
|
||||
# Draw text
|
||||
if config.showText:
|
||||
let textWidth = canvas.getTextWidth(cfg.text).float
|
||||
let textX = (buttonWidth - textWidth) / 2
|
||||
canvas.drawText(cfg.text, textX.int, y.int)
|
||||
y += config.fontSize.float + 5 # Add some padding after the text
|
||||
|
||||
# Draw shortcut
|
||||
if config.showshortcuttext:
|
||||
let shortcutText = "(" & cfg.shortcut & ")"
|
||||
let shortcutWidth = canvas.getTextWidth(shortcutText).float
|
||||
let shortcutX = (buttonWidth - shortcutWidth) / 2
|
||||
canvas.drawText(shortcutText, shortcutX.int, y.int)
|
||||
|
||||
button.onClick = proc(event: ClickEvent) =
|
||||
action()
|
||||
|
||||
return button
|
||||
|
||||
|
||||
proc main() =
|
||||
let config = loadConfig()
|
||||
app.init()
|
||||
|
||||
var window = newWindow()
|
||||
window.width = config.window.width
|
||||
window.height = config.window.height
|
||||
window.title = config.window.title
|
||||
|
||||
var container = newLayoutContainer(Layout_Vertical)
|
||||
container.widthMode = WidthMode_Fill
|
||||
container.heightMode = HeightMode_Fill
|
||||
|
||||
container.onDraw = proc (event: DrawEvent) =
|
||||
let canvas = event.control.canvas
|
||||
canvas.areaColor = hexToRgb(config.window.backgroundColor)
|
||||
canvas.drawRectArea(0, 0, window.width, window.height)
|
||||
|
||||
window.add(container)
|
||||
|
||||
# Top spacer
|
||||
var spacerTop = newControl()
|
||||
spacerTop.widthMode = WidthMode_Fill
|
||||
spacerTop.heightMode = HeightMode_Expand
|
||||
container.add(spacerTop)
|
||||
|
||||
# Button container
|
||||
var buttonContainer = newLayoutContainer(Layout_Horizontal)
|
||||
buttonContainer.widthMode = WidthMode_Fill
|
||||
buttonContainer.height = config.buttonHeight + (2 * config.buttonPadding)
|
||||
|
||||
buttonContainer.onDraw = proc (event: DrawEvent) =
|
||||
let canvas = event.control.canvas
|
||||
canvas.areaColor = hexToRgb(config.window.backgroundColor)
|
||||
canvas.drawRectArea(0, 0, buttonContainer.width, buttonContainer.height)
|
||||
|
||||
container.add(buttonContainer)
|
||||
|
||||
# Left spacer in button container
|
||||
var spacerLeft = newControl()
|
||||
spacerLeft.widthMode = WidthMode_Expand
|
||||
spacerLeft.heightMode = HeightMode_Fill
|
||||
buttonContainer.add(spacerLeft)
|
||||
|
||||
proc logout() {.closure.} =
|
||||
for program in config.programsToTerminate:
|
||||
terminate(program)
|
||||
let desktop = getDesktopEnvironment()
|
||||
|
||||
if desktop == "hyprland":
|
||||
discard execCmd("hyprctl dispatch exit")
|
||||
else:
|
||||
terminate(desktop)
|
||||
quit(0)
|
||||
|
||||
let actions = {
|
||||
"cancel": proc() {.closure.} = app.quit(),
|
||||
"logout": logout,
|
||||
"reboot": proc() {.closure.} = discard execCmd("systemctl reboot"),
|
||||
"shutdown": proc() {.closure.} = discard execCmd("systemctl poweroff"),
|
||||
"suspend": proc() {.closure.} = discard execCmd("systemctl suspend"),
|
||||
"hibernate": proc() {.closure.} = discard execCmd("systemctl hibernate"),
|
||||
"lock": proc() {.closure.} =
|
||||
if config.lockScreenApp != "":
|
||||
discard execCmd(config.lockScreenApp)
|
||||
else:
|
||||
discard execCmd("loginctl lock-session")
|
||||
}.toTable
|
||||
|
||||
for i, key in config.buttonOrder:
|
||||
if key in config.buttons and key in actions:
|
||||
if i > 0: # Add spacing between buttons, but not before the first button
|
||||
var spacing = newControl()
|
||||
spacing.width = config.buttonPadding
|
||||
buttonContainer.add(spacing)
|
||||
|
||||
var button = createButton(config.buttons[key], config, key, actions[key])
|
||||
buttonContainer.add(button)
|
||||
|
||||
# Right spacer in button container
|
||||
var spacerRight = newControl()
|
||||
spacerRight.widthMode = WidthMode_Expand
|
||||
spacerRight.heightMode = HeightMode_Fill
|
||||
buttonContainer.add(spacerRight)
|
||||
|
||||
# Bottom spacer
|
||||
var spacerBottom = newControl()
|
||||
spacerBottom.widthMode = WidthMode_Fill
|
||||
spacerBottom.heightMode = HeightMode_Expand
|
||||
container.add(spacerBottom)
|
||||
|
||||
window.onKeyDown = proc(event: KeyboardEvent) =
|
||||
let keyString = standardizeKeyName($event.key)
|
||||
for key, cfg in config.buttons:
|
||||
let standardizedShortcut = standardizeKeyName(cfg.shortcut)
|
||||
if standardizedShortcut == keyString:
|
||||
if key in actions:
|
||||
actions[key]()
|
||||
return
|
||||
|
||||
window.show()
|
||||
app.run()
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user