Minor changes

This commit is contained in:
2020-06-04 18:15:27 +02:00
parent 06901c72c0
commit 13cf05bf99
4 changed files with 60 additions and 41 deletions

View File

@@ -37,7 +37,7 @@ proc setTimeout*(seconds: string) =
when isMainModule: when isMainModule:
var p = newParser("pixctrl"): var p = newParser("pixctrl"):
help("Control utilitiy for randopix") help("Control utilitiy for randopix")
option("-s", "--server", help="Host running the randopix server", default="http://localhost/") option("-s", "--server", help="Host running the randopix server", default="http://localhost:8080/")
run: run:
randopixServer = opts.server randopixServer = opts.server

View File

@@ -1,4 +1,4 @@
import os, sets, random, httpClient, json, strformat, options import os, sets, random, httpClient, json, strformat, options, deques
import gintro/[gdkpixbuf, gobject] import gintro/[gdkpixbuf, gobject]
import common import common
@@ -6,7 +6,6 @@ const
supportedExts = @[".png", ".jpg", ".jpeg"] supportedExts = @[".png", ".jpg", ".jpeg"]
foxesUrl = "https://randomfox.ca/floof/" foxesUrl = "https://randomfox.ca/floof/"
inspiroUrl = "http://inspirobot.me/api?generate=true" inspiroUrl = "http://inspirobot.me/api?generate=true"
tmpFile = "/tmp/randopix_tmp.png"
type type
FileOpResult* = object of OpResult FileOpResult* = object of OpResult
@@ -18,17 +17,18 @@ type
mode* : Mode ## Selects the API that is used to get images mode* : Mode ## Selects the API that is used to get images
path*: Option[string] ## Path on the local file syetem that will be used in `file` mode path*: Option[string] ## Path on the local file syetem that will be used in `file` mode
exts: HashSet[string] ## Allowed extensions that the `file` mode will display exts: HashSet[string] ## Allowed extensions that the `file` mode will display
files: seq[string] ## Currently loaded list of images in `file` mode
var var
client = newHttpClient() ## For loading images from the web client = newHttpClient() ## For loading images from the web
tmpDir = getTempDir() / "randopix"
tmpFile = tmpDir / "tmp.png"
fileList = initDeque[string]()
######################## ########################
# Constructors # Constructors
######################## ########################
proc newImageProvider(verbose: bool, mode: Mode, path: Option[string]): ImageProvider = proc newImageProvider(verbose: bool, mode: Mode, path: Option[string]): ImageProvider =
randomize()
ImageProvider(verbose: verbose, mode: mode, path: path, exts: supportedExts.toHashSet) ImageProvider(verbose: verbose, mode: mode, path: path, exts: supportedExts.toHashSet)
proc newImageProvider*(verbose: bool): ImageProvider = proc newImageProvider*(verbose: bool): ImageProvider =
@@ -94,20 +94,24 @@ proc getLocalFile(ip: var ImageProvider): FileOpResult =
# First, check if there are still images left to be loaded. # First, check if there are still images left to be loaded.
# If not reread all files from the path # If not reread all files from the path
if ip.files.len < 1: if fileList.len == 0:
if ip.path.isNone: var tmp: seq[string]
return newFileOpResultError("No path for image loading") var split: tuple[dir, name, ext: string]
ip.log "Reloading file list..."
for file in walkDirRec(ip.path.get): for file in walkDirRec(ip.path.get):
let split = splitFile(file) split = splitFile(file)
if ip.exts.contains(split.ext): if ip.exts.contains(split.ext):
ip.files.add(file) tmp.add($file)
ip.log fmt"Loaded {ip.files.len} files"
shuffle(ip.files)
ip.log fmt"Loaded {tmp.len} files"
shuffle(tmp)
for file in tmp:
fileList.addLast(file)
if fileList.len == 0:
return newFileOpResultError("No files found")
let next = fileList.popFirst()
# Remove the current file after # Remove the current file after
result = newFileOpResult(ip.files[0]) result = newFileOpResult(next)
ip.files.delete(0)
proc getFileName(ip: var ImageProvider): FileOpResult = proc getFileName(ip: var ImageProvider): FileOpResult =
## Get the temporary file name of the next file to display ## Get the temporary file name of the next file to display
@@ -151,7 +155,10 @@ proc next*(ip: var ImageProvider, width, height: int): FileOpResult =
return newFileOpResultError("Error while saving temporary image") return newFileOpResultError("Error while saving temporary image")
# GTK pixbuf leaks memory when not manually decreasing reference count # GTK pixbuf leaks memory when not manually decreasing reference count
pixbuf.genericGObjectUnref() pixbuf.unref()
rawPixbuf.genericGObjectUnref() rawPixbuf.unref()
newFileOpResult(tmpFile) newFileOpResult(tmpFile)
createDir(tmpDir)
randomize()

View File

@@ -28,6 +28,7 @@ var
# Widgets # Widgets
window: ApplicationWindow window: ApplicationWindow
label: Label label: Label
box: Box
# Server vor recieving commands from external tools # Server vor recieving commands from external tools
serverWorker: system.Thread[ServerArgs] serverWorker: system.Thread[ServerArgs]
@@ -35,14 +36,14 @@ proc log(things: varargs[string, `$`]) =
if args.verbose: if args.verbose:
echo things.join() echo things.join()
proc notify(label: Label, message: string = "") = proc notify(label: Label, things: varargs[string, `$`]) =
## Shows the notification box in the lower left corner. ## Shows the notification box in the lower left corner.
## If no message is passed, the box will be hidden ## If no message is passed, the box will be hidden
label.text = message label.text = things.join()
if (message == ""): if (label.text == ""):
label.hide box.hide
else: else:
label.show box.show
proc newArgs(): Option[Args] = proc newArgs(): Option[Args] =
let p = newParser("randopix"): let p = newParser("randopix"):
@@ -50,7 +51,7 @@ proc newArgs(): Option[Args] =
option("-m", "--mode", help="The image source mode.", choices=enumToStrings(Mode)) option("-m", "--mode", help="The image source mode.", choices=enumToStrings(Mode))
option("-d", "--directoy", help="Path to a directory with images for the 'file' mode") option("-d", "--directoy", help="Path to a directory with images for the 'file' mode")
option("-t", "--timeout", help="Seconds before the image is refreshed", default="300") option("-t", "--timeout", help="Seconds before the image is refreshed", default="300")
option("-p", "--port", help="Port over which the control server should be accessible", default="80") option("-p", "--port", help="Port over which the control server should be accessible", default="8080")
flag("-w", "--windowed", help="Do not start in fullscreen mode") flag("-w", "--windowed", help="Do not start in fullscreen mode")
flag("-v", "--verbose", help="Show more information") flag("-v", "--verbose", help="Show more information")
@@ -115,7 +116,7 @@ proc updateImage(image: Image): bool =
e = getCurrentException() e = getCurrentException()
msg = getCurrentExceptionMsg() msg = getCurrentExceptionMsg()
log "Got exception ", repr(e), " with message ", msg log "Got exception ", repr(e), " with message ", msg
label.notify "Error while refreshing image, retrying..." label.notify "Error while refreshing, retrying..."
return false return false
proc timedUpdate(image: Image): bool = proc timedUpdate(image: Image): bool =
@@ -124,8 +125,8 @@ proc timedUpdate(image: Image): bool =
return false return false
proc forceUpdate(action: SimpleAction; parameter: Variant; image: Image): void = proc forceUpdate(action: SimpleAction; parameter: Variant; image: Image): void =
log "Refreshing image..." log "Refreshing..."
label.notify "Refreshing image..." label.notify "Refreshing..."
if updateTimeout > 0: if updateTimeout > 0:
discard updateTimeout.remove discard updateTimeout.remove
updateTimeout = int(timeoutAdd(500, timedUpdate, image)) updateTimeout = int(timeoutAdd(500, timedUpdate, image))
@@ -152,8 +153,10 @@ proc checkServerChannel(image: Image): bool =
of cMode: of cMode:
try: try:
let mode = parseEnum[Mode](msg.parameter) let mode = parseEnum[Mode](msg.parameter)
log "Switching mode: ", mode
imageProvider.mode = mode imageProvider.mode = mode
forceUpdate(nil, nil, image)
log "Switching mode: ", mode
label.notify fmt"Switch Mode: {msg.parameter.capitalizeAscii()}"
except ValueError: except ValueError:
log "Invalid mode: ", msg.parameter log "Invalid mode: ", msg.parameter
@@ -171,11 +174,11 @@ proc toggleFullscreen(action: SimpleAction; parameter: Variant; window: Applicat
window.fullscreen window.fullscreen
args.fullscreen = not args.fullscreen args.fullscreen = not args.fullscreen
proc toggleHelp(action: SimpleAction; parameter: Variant; label: Label) = proc toggleHelp(action: SimpleAction; parameter: Variant; box: Box) =
if label.visible: if box.visible:
label.hide box.hide
else: else:
label.show box.show
proc cleanUp(w: ApplicationWindow, app: Application) = proc cleanUp(w: ApplicationWindow, app: Application) =
## Stop the control server and exit the GTK application ## Stop the control server and exit the GTK application
@@ -207,16 +210,25 @@ proc appActivate(app: Application) =
# Create all windgets we are gonna use # Create all windgets we are gonna use
label = newLabel(fmt"Starting ('H' for help)...") label = newLabel(fmt"Starting ('H' for help)...")
label.halign = Align.`end`
label.valign = Align.`end` let spinner = newSpinner()
spinner.start()
box = newBox(Orientation.horizontal, 2)
box.halign = Align.`end`
box.valign = Align.`end`
box.packStart(spinner, true, true, 10)
box.packStart(label, true, true, 0)
let helpText = newLabel(helpString) let helpText = newLabel(helpString)
helpText.halign = Align.start let helpBox = newBox(Orientation.vertical, 0)
helpText.valign = Align.start helpBox.packStart(helpText, true, true, 0)
helpBox.halign = Align.start
helpBox.valign = Align.start
let container = newOverlay() let container = newOverlay()
container.addOverlay(label) container.addOverlay(box)
container.addOverlay(helpText) container.addOverlay(helpBox)
window.add(container) window.add(container)
let image = newImage() let image = newImage()
@@ -244,7 +256,7 @@ proc appActivate(app: Application) =
window.actionMap.addAction(action) window.actionMap.addAction(action)
action = newSimpleAction("help") action = newSimpleAction("help")
discard action.connect("activate", toggleHelp, helpText) discard action.connect("activate", toggleHelp, helpBox)
app.setAccelsForAction("win.help", "H") app.setAccelsForAction("win.help", "H")
window.actionMap.addAction(action) window.actionMap.addAction(action)
@@ -252,7 +264,7 @@ proc appActivate(app: Application) =
window.showAll window.showAll
# Help is only shown on demand # Help is only shown on demand
helpText.hide helpBox.hide
# Setting the inital image # Setting the inital image
# Fix 1 second timeout to make sure all other initialization has finished # Fix 1 second timeout to make sure all other initialization has finished

View File

@@ -2,7 +2,7 @@ window {
background: black; background: black;
font-size: 30px; font-size: 30px;
} }
label { box {
background-color: rgba(255, 255, 255, .75); background-color: rgba(255, 255, 255, .75);
border: 2px solid gray; border: 2px solid gray;
border-radius: 5px; border-radius: 5px;