Add info notification.

This commit is contained in:
2020-05-15 21:34:22 +02:00
parent 9e63f77e61
commit e7a5934e9a
3 changed files with 122 additions and 61 deletions

View File

@@ -1,4 +1,8 @@
import os, sets, random import os, sets, random
const
supportedExts = @[".png", ".jpg", ".jpeg"]
type type
FileProvider* = ref object FileProvider* = ref object
exts: HashSet[string] exts: HashSet[string]
@@ -25,5 +29,5 @@ proc next*(fp: FileProvider): string =
fp.files.delete(0) fp.files.delete(0)
proc newFileProvider*(path: string): FileProvider = proc newFileProvider*(path: string): FileProvider =
result = FileProvider(path: path, exts: [".png", ".jpg", ".jpeg"].toHashSet) result = FileProvider(path: path, exts: supportedExts.toHashSet)
result.load result.load

View File

@@ -1,7 +1,8 @@
import httpClient, json, os, options, strformat import httpClient, json, os, options, strformat
import gintro/[gtk, glib, gobject, gio, gdkpixbuf] import gintro/[gtk, glib, gobject, gio, gdkpixbuf]
import gintro/gdk except Window
import argparse except run import argparse except run
import fileAccess import fileAccess, style
const const
version = "0.1" version = "0.1"
@@ -13,18 +14,62 @@ type
Inspiro = "inspiro" ## Inspiring nonsense Inspiro = "inspiro" ## Inspiring nonsense
File = "file" ## Images from a local path File = "file" ## Images from a local path
Args = object
fullscreen: bool ## Applicaion is show in fullscreen mode
verbose: bool ## More debug information in notification label
mode: Option[Mode] ## The chosen image source
path: string ## File mode only: the path to the images
var var
client = newHttpClient() client = newHttpClient() ## For loading images from the web
fileProvider: FileProvider ## Gets images from the chosen source
args: Args ## The parsed command line args
# Widgets
window: ApplicationWindow window: ApplicationWindow
imageWidget: Image imageWidget: Image
fullscreen = true label: Label
mode: Option[Mode]
fileProvider: FileProvider proc enumToStrings(en: typedesc): seq[string] =
argParser = newParser("randopix"): for x in en:
result.add $x
proc notify(label: Label, message: string = "") =
## Shows the notification box in the lower left corner.
## If no message is passed, the box will be hidden
label.text = message
if (message == ""):
label.hide
else:
label.show
proc newArgs(): Args =
let p = newParser("randopix"):
help(fmt"Version {version} - Display random images from different sources") help(fmt"Version {version} - Display random images from different sources")
option("-m", "--mode", help="foxes, file, inspiro, inspiro-xmas") option("-m", "--mode", help="The image source mode.", choices=enumToStrings(Mode))
option("-p", "--path", help="('file' mode only) Path to a directory with images") option("-p", "--path", help="Path to a directory with images ('file' mode only)")
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")
let opts = p.parse(commandLineParams())
var mode: Option[Mode]
if (opts.mode == ""):
echo p.help
return
try:
mode = some(parseEnum[Mode](opts.mode))
except ValueError:
echo fmt"Invaild mode: {opts.mode}"
echo p.help
return
if (mode.get == Mode.File):
fileProvider = newFileProvider(opts.path)
Args(
fullscreen: not opts.windowed,
verbose: opts.verbose,
mode: mode,
path: opts.path)
proc downloadFox(): Pixbuf = proc downloadFox(): Pixbuf =
let urlData = client.getContent(floofUrl) let urlData = client.getContent(floofUrl)
@@ -34,27 +79,15 @@ proc downloadFox(): Pixbuf =
discard loader.write(imageData) discard loader.write(imageData)
loader.getPixbuf() loader.getPixbuf()
proc getLocalImage(): Pixbuf = proc getLocalImage(): Pixbuf =
## let the file provider serve another image ## let the file provider serve another image
fileProvider.next.newPixbufFromFile fileProvider.next.newPixbufFromFile
proc resizeImage(pixbuf: Pixbuf): Pixbuf = proc tryGetImage(): Option[Pixbuf] =
var wWidth, wHeight, width, height: int ## Get the raw image from an image provider
window.getSize(wWidth, wHeight) ## The kind of image is based on the command line args
if args.mode.isSome:
if (wWidth > wHeight): case args.mode.get
height = wHeight
width = ((pixbuf.width * height) / pixbuf.height).toInt
else:
width = wWidth
height = ((pixbuf.height * width) / pixbuf.width).toInt
pixbuf.scaleSimple(width, height, InterpType.bilinear)
proc getImage(): Option[Pixbuf] =
if mode.isSome:
case mode.get
of Mode.Foxes: of Mode.Foxes:
result = some(downloadFox()) result = some(downloadFox())
of Mode.Inspiro: of Mode.Inspiro:
@@ -63,27 +96,40 @@ proc getImage(): Option[Pixbuf] =
result = some(getLocalImage()) result = some(getLocalImage())
proc updateImage(action: SimpleAction; parameter: Variant;) = proc updateImage(action: SimpleAction; parameter: Variant;) =
let data = getImage(); ## Updates the UI with a new image
if (data.isNone): return # Loading new image
var pixbuf = data.get().resizeImage() let data = tryGetImage();
if data.isNone:
label.notify "No image to display..."
return;
## Resize image to best fit the window
var pixbuf = data.get()
var wWidth, wHeight, width, height: int
window.getSize(wWidth, wHeight)
if (wWidth > wHeight):
height = wHeight
width = ((pixbuf.width * height) / pixbuf.height).toInt
else:
width = wWidth
height = ((pixbuf.height * width) / pixbuf.width).toInt
pixbuf = pixbuf.scaleSimple(width, height, InterpType.bilinear)
# Update the UI with the image
imageWidget.setFromPixbuf(pixbuf) imageWidget.setFromPixbuf(pixbuf)
label.notify
proc toggleFullscreen(action: SimpleAction; parameter: Variant; window: ApplicationWindow) = proc toggleFullscreen(action: SimpleAction; parameter: Variant; window: ApplicationWindow) =
if fullscreen: ## Fullscreen toggle event
if args.fullscreen:
window.unfullscreen window.unfullscreen
else: else:
window.fullscreen window.fullscreen
fullscreen = not fullscreen args.fullscreen = not args.fullscreen
proc quit(action: SimpleAction; parameter: Variant; app: Application) = proc quit(action: SimpleAction; parameter: Variant; app: Application) =
app.quit() ## Application quit event
app.quit()
proc applyStyle(window: Window) =
let cssProvider = newCssProvider()
let data = "window { background: black; }"
discard cssProvider.loadFromData(data)
let styleContext = window.getStyleContext()
styleContext.addProvider(cssProvider, STYLE_PROVIDER_PRIORITY_USER)
proc connectSignals(app: Application) = proc connectSignals(app: Application) =
## Connect th GTK signals to the procs ## Connect th GTK signals to the procs
@@ -102,38 +148,35 @@ proc connectSignals(app: Application) =
app.setAccelsForAction("win.update", "U") app.setAccelsForAction("win.update", "U")
window.actionMap.addAction(updateImageAction) window.actionMap.addAction(updateImageAction)
proc parseArgs(): void =
## Parse and apply options from the command line
let opts = argparser.parse(commandLineParams())
fullscreen = not opts.windowed
if (opts.mode != ""):
try:
mode = some(parseEnum[Mode](opts.mode))
except ValueError:
echo "Invaild image source: ", opts.mode
if (mode.isSome and mode.get == Mode.File):
fileProvider = newFileProvider(opts.path)
proc appActivate(app: Application) = proc appActivate(app: Application) =
parseArgs() # Parse arguments from the command line
args = newArgs()
# No mode was given, exit and display the help text # No mode was given, exit and display the help text
if (mode.isNone): if (args.mode.isNone): return
echo argParser.help
return
window = newApplicationWindow(app) window = newApplicationWindow(app)
window.title = "randopix" window.title = "randopix"
window.setKeepAbove(true) window.setKeepAbove(true)
window.setDefaultSize(600, 600) window.setDefaultSize(800, 600)
# Custom styling for e.g. the background color # Custom styling for e.g. the background color CSS data is in the "style.nim" module
window.applyStyle let provider = newCssProvider()
discard provider.loadFromData(css)
addProviderForScreen(getDefaultScreen(), provider, STYLE_PROVIDER_PRIORITY_USER)
# Create all windgets we are gonna use
var overlay = newOverlay()
imageWidget = newImage() imageWidget = newImage()
window.add(imageWidget) label = newLabel("Starting...")
label.halign = Align.`end`
label.valign = Align.`end`
if fullscreen: overlay.addOverlay(label)
overlay.add(imageWidget)
window.add(overlay)
if args.fullscreen:
window.fullscreen window.fullscreen
app.connectSignals app.connectSignals

14
src/style.nim Normal file
View File

@@ -0,0 +1,14 @@
import strutils
const css* = """
window {
background: black;
font-size: 30px;
}
label {
background-color: #fff;
border: 2px solid gray;
border-radius: 5px;
margin: 10px;
padding: 10px;
}
""".unindent