Minor changes
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user