From 89237f7d36023f85a85309f231d16cbe09513d47 Mon Sep 17 00:00:00 2001 From: Lettier Date: Tue, 18 Aug 2020 02:00:09 -0400 Subject: [PATCH] Updates to version 6.0.1.0. --- CHANGELOG.md | 17 ++ Gifcurry.cabal | 31 ++-- README.md | 12 +- docs/index.html | 4 +- makefile | 2 +- .../app-image/gifcurry-app-image-install.sh | 2 +- packaging/linux/arch-aur/PKGBUILD | 2 +- packaging/linux/snap/snapcraft.yaml | 2 +- src/data/gui.glade | 4 +- src/gui/GuiMisc.hs | 24 +++ src/gui/GuiPreview.hs | 172 ++++++++++++------ src/gui/GuiRecords.hs | 55 +++--- src/gui/Main.hs | 48 ++++- src/lib/Gifcurry.hs | 2 +- stack.yaml | 28 +-- stack.yaml.lock | 90 ++++----- 16 files changed, 323 insertions(+), 172 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bed3171..cfe5112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ ## Changelog +### 6.0.1.0 + +#### Added + +- GUI + - Loads a file if passed during opening + +#### Changed + +- GUI + - Reloads the file when reopening the current file + - Adjusts window size to screen size + +#### Removed + +- + ### 6.0.0.0 #### Added diff --git a/Gifcurry.cabal b/Gifcurry.cabal index fc8b0dd..5aa1dab 100644 --- a/Gifcurry.cabal +++ b/Gifcurry.cabal @@ -1,5 +1,5 @@ name: Gifcurry -version: 6.0.0.0 +version: 6.0.1.0 synopsis: GIF creation utility. description: The open-source, Haskell-built video editor for GIF makers. homepage: https://github.com/lettier/gifcurry @@ -143,31 +143,34 @@ library executable gifcurry_gui main-is: Main.hs build-depends: base == 4.11.* - , haskell-gi == 0.22.6 - , haskell-gi-base == 0.22.2 - , gi-gobject == 2.0.21 - , gi-gio == 2.0.24 - , gi-glib == 2.0.22 - , gi-pango == 1.0.21 - , gi-gdk == 3.0.21 - , gi-gdkpixbuf == 2.0.22 - , gi-gtk == 3.0.31 - , gi-cairo == 1.0.22 - , gi-gstbase == 1.0.21 - , gi-gst == 1.0.21 - , gi-gstvideo == 1.0.21 + , haskell-gi == 0.23.0 + , haskell-gi-base == 0.23.0 + , gi-gobject == 2.0.22 + , gi-gio == 2.0.25 + , gi-glib == 2.0.23 + , gi-pango == 1.0.22 + , gi-gdk == 3.0.22 + , gi-gdkpixbuf == 2.0.23 + , gi-gtk == 3.0.32 + , gi-cairo == 1.0.23 + , gi-gstbase == 1.0.22 + , gi-gst == 1.0.22 + , gi-gstvideo == 1.0.22 , cairo == 0.13.* , pango == 0.13.* , process >= 1.6.2.0 , temporary >= 1.2 && < 1.3 , directory == 1.3.* , text == 1.2.* + , time == 1.8.0.2 , filepath == 1.4.* , filemanip == 0.3.6.* , transformers == 0.5.* , pureMD5 == 2.1.* , bytestring == 0.10.* , yaml == 0.8.26.* + , system-filepath == 0.4.14 + , system-fileio == 0.3.16.4 other-modules: Paths_Gifcurry , GuiRecords , GuiCapabilities diff --git a/README.md b/README.md index c47bc46..ab37f00 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ gifcurry_cli \           ▀▀▀▀▀▀▀                                                                              -Gifcurry 6.0.0.0 +Gifcurry 6.0.1.0 (C) 2016 David Lettier lettier.com @@ -252,15 +252,15 @@ To find the latest version of Gifcurry, head over to the ### I use Linux. :penguin: If you use Linux then the easiest way to grab a copy of Gifcurry is by downloading the -[AppImage](https://github.com/lettier/gifcurry/releases/download/6.0.0.0/gifcurry-6.0.0.0-x86_64.AppImage). +[AppImage](https://github.com/lettier/gifcurry/releases/download/6.0.1.0/gifcurry-6.0.1.0-x86_64.AppImage). After you download the -[AppImage](https://github.com/lettier/gifcurry/releases/download/6.0.0.0/gifcurry-6.0.0.0-x86_64.AppImage), +[AppImage](https://github.com/lettier/gifcurry/releases/download/6.0.1.0/gifcurry-6.0.1.0-x86_64.AppImage), right click on it, select permissions, and check the box near execute. With that out of the way—you're all set—just double click on the AppImage and the GUI will fire right up. You can also download and install the -[AppImage](https://github.com/lettier/gifcurry/releases/download/6.0.0.0/gifcurry-6.0.0.0-x86_64.AppImage) +[AppImage](https://github.com/lettier/gifcurry/releases/download/6.0.1.0/gifcurry-6.0.1.0-x86_64.AppImage) using the handy [AppImage install script](https://raw.githubusercontent.com/lettier/gifcurry/master/packaging/linux/app-image/gifcurry-app-image-install.sh) (right click and save link as). @@ -268,7 +268,7 @@ Download the script, right click on it, select permissions, check the box near e You should now see Gifcurry listed alongside your other installed programs. If you want the CLI then download the -[prebuilt version](https://github.com/lettier/gifcurry/releases/download/6.0.0.0/gifcurry-linux-6.0.0.0.tar.gz) +[prebuilt version](https://github.com/lettier/gifcurry/releases/download/6.0.1.0/gifcurry-linux-6.0.1.0.tar.gz) for Linux, extract it, open up your terminal, `cd` to the bin folder, and then run `gifcurry_cli -?`. As an added bonus, inside the bin directory is the GUI version @@ -312,7 +312,7 @@ The [Gifcurry snap](https://snapcraft.io/gifcurry) only comes with the GUI. If you want the CLI, download the -[prebuilt version](https://github.com/lettier/gifcurry/releases/download/6.0.0.0/gifcurry-linux-6.0.0.0.tar.gz) +[prebuilt version](https://github.com/lettier/gifcurry/releases/download/6.0.1.0/gifcurry-linux-6.0.1.0.tar.gz) for Linux. ### I use Mac. :apple: diff --git a/docs/index.html b/docs/index.html index 2848015..0895de0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -126,8 +126,8 @@

ImageMagick.

Linux users can download the - AppImage or - the prebuilt binaries. + AppImage or + the prebuilt binaries. If you'd rather install it, you can do so via pacman (Arch) or diff --git a/makefile b/makefile index 11184fd..507e185 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,7 @@ .RECIPEPREFIX != ps -_GIFCURRY_VERSION="6.0.0.0" +_GIFCURRY_VERSION="6.0.1.0" _STACK=stack --allow-different-user _GHC_VERSION=`$(_STACK) ghc -- --version | sed 's|The Glorious Glasgow Haskell Compilation System, version ||g'` _STACK_PATH_LOCAL_BIN=`$(_STACK) path --local-bin` diff --git a/packaging/linux/app-image/gifcurry-app-image-install.sh b/packaging/linux/app-image/gifcurry-app-image-install.sh index 2ab54f1..3667bec 100755 --- a/packaging/linux/app-image/gifcurry-app-image-install.sh +++ b/packaging/linux/app-image/gifcurry-app-image-install.sh @@ -3,7 +3,7 @@ # (C) 2017 David Lettier # lettier.com -GIFCURRY_VERSION="6.0.0.0" +GIFCURRY_VERSION="6.0.1.0" GIFCURRY_RELEASES_DOWNLOAD="https://github.com/lettier/gifcurry/releases/download/$GIFCURRY_VERSION" GIFCURRY_PACKAGING_LINUX_COMMON="https://raw.githubusercontent.com/lettier/gifcurry/master/packaging/linux/common" GIFCURRY_APP_IMAGE="gifcurry-$GIFCURRY_VERSION-x86_64.AppImage" diff --git a/packaging/linux/arch-aur/PKGBUILD b/packaging/linux/arch-aur/PKGBUILD index 7423948..3a61c30 100755 --- a/packaging/linux/arch-aur/PKGBUILD +++ b/packaging/linux/arch-aur/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Lettier _name=gifcurry -_ver=6.0.0.0 +_ver=6.0.1.0 _xrev=0 pkgname=${_name} diff --git a/packaging/linux/snap/snapcraft.yaml b/packaging/linux/snap/snapcraft.yaml index 00fd0df..b048a94 100644 --- a/packaging/linux/snap/snapcraft.yaml +++ b/packaging/linux/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: gifcurry -version: '6.0.0.0' +version: '6.0.1.0' summary: The open-source, Haskell-built video editor for GIF makers. type: app description: | diff --git a/src/data/gui.glade b/src/data/gui.glade index 17eaf19..d5320d3 100644 --- a/src/data/gui.glade +++ b/src/data/gui.glade @@ -456,7 +456,7 @@ Author: David Lettier False Gifcurry mouse - 1100 + 1000 gifcurry-icon.svg center @@ -1587,7 +1587,7 @@ Gifcurry was created by me, David Lettier. For more information visit <a href </span> <big><big><b>VERSION</b></big></big> <span font-size="large"> -6.0.0.0 +6.0.1.0 </span> <big><big><b>KEYS</b></big></big> <span font-size="large"> diff --git a/src/gui/GuiMisc.hs b/src/gui/GuiMisc.hs index ec620f3..389ec59 100644 --- a/src/gui/GuiMisc.hs +++ b/src/gui/GuiMisc.hs @@ -14,12 +14,15 @@ import System.Process import System.Directory import Control.Exception import Control.Monad +import Filesystem +import Filesystem.Path.CurrentOS import Text.Read import Data.Int import Data.Word import Data.Maybe import Data.Char import Data.Text +import Data.Time import Data.List import Data.GI.Base.Overloading import qualified GI.Gtk @@ -242,3 +245,24 @@ toggleToggleButtonLabel toggleClass toggleButton "gifcurry-font-weight-bold" + +getEpochTimestamp + :: IO Int +getEpochTimestamp + = + read . formatTime defaultTimeLocale "%s" <$> getCurrentTime + +toAbsoluteUri + :: String + -> IO String +toAbsoluteUri + uri + = do + cwd <- getWorkingDirectory + let cwd' = + case toText cwd of + Right x -> x + Left y -> y + if isRelative uri + then return $ normalise $ combine (Data.Text.unpack cwd') uri + else return uri diff --git a/src/gui/GuiPreview.hs b/src/gui/GuiPreview.hs index fbf27da..02898de 100644 --- a/src/gui/GuiPreview.hs +++ b/src/gui/GuiPreview.hs @@ -57,9 +57,6 @@ blankPreviewIcon = "gtk-discard" framePreviewDirectoryName :: String framePreviewDirectoryName = "gifcurry-frame-previews" -desiredPreviewSize :: Double -desiredPreviewSize = 700.0 - buildVideoPreviewWidgetAndPlaybinElement :: IO (Maybe GI.Gtk.Widget, Maybe GI.Gst.Element) buildVideoPreviewWidgetAndPlaybinElement = do maybeGtkSink <- GI.Gst.elementFactoryMake "gtksink" (Just "MultimediaPlayerGtkSink") @@ -195,11 +192,13 @@ preview = do GR.GuiInFileProperties { GR.inFileUri = inFilePath + , GR.inFileLoadedAt , GR.inFileWidth , GR.inFileHeight } <- readIORef guiInFilePropertiesRef GR.GuiPreviewState { GR.maybeInFilePath + , GR.maybeInFileLoadedAt , GR.maybeStartTime , GR.maybeEndTime , GR.maybeColorCount @@ -209,14 +208,16 @@ preview endTime <- GI.Gtk.spinButtonGetValue endTimeSpinButton colorCount <- GI.Gtk.spinButtonGetValue colorCountSpinButton dither <- GI.Gtk.toggleButtonGetActive ditherToggleButton - let invalidInFilePath = inFilePath == "" - let invalidStartTime = startTime < 0.0 - let invalidEndTime = endTime <= 0.0 - let invalidInFileWidth = inFileWidth <= 0.0 - let invalidInFileHeight = inFileHeight <= 0.0 - let invalidColorCount = colorCount < 1 || colorCount > 256 - let inputInvalid = + let invalidInFilePath = inFilePath == "" + let invalidInFileLoadedAtChanged = inFileLoadedAt < 0 + let invalidStartTime = startTime < 0.0 + let invalidEndTime = endTime <= 0.0 + let invalidInFileWidth = inFileWidth <= 0.0 + let invalidInFileHeight = inFileHeight <= 0.0 + let invalidColorCount = colorCount < 1 || colorCount > 256 + let inputInvalid = invalidInFilePath + || invalidInFileLoadedAtChanged || invalidStartTime || invalidEndTime || invalidInFileWidth @@ -226,19 +227,20 @@ preview then previewFunction GR.GuiPreviewFunctionArgs - { GR.guiComponents = guiComponents - , GR.inFilePath = inFilePath - , GR.startTime = startTime - , GR.endTime = endTime - , GR.colorCount = colorCount - , GR.dither = dither - , GR.inFileWidth = inFileWidth - , GR.inFileHeight = inFileHeight - , GR.inFilePathChanged = fromMaybe "" maybeInFilePath /= inFilePath - , GR.startTimeChanged = fromMaybe (-1.0) maybeStartTime /= startTime - , GR.endTimeChanged = fromMaybe (-1.0) maybeEndTime /= endTime - , GR.colorCountChanged = fromMaybe (-1.0) maybeColorCount /= colorCount - , GR.ditherChanged = fromMaybe False maybeDither /= dither + { GR.guiComponents = guiComponents + , GR.inFilePath = inFilePath + , GR.startTime = startTime + , GR.endTime = endTime + , GR.colorCount = colorCount + , GR.dither = dither + , GR.inFileWidth = inFileWidth + , GR.inFileHeight = inFileHeight + , GR.inFilePathChanged = fromMaybe "" maybeInFilePath /= inFilePath + , GR.inFileLoadedAtChanged = fromMaybe 0 maybeInFileLoadedAt /= inFileLoadedAt + , GR.startTimeChanged = fromMaybe (-1.0) maybeStartTime /= startTime + , GR.endTimeChanged = fromMaybe (-1.0) maybeEndTime /= endTime + , GR.colorCountChanged = fromMaybe (-1.0) maybeColorCount /= colorCount + , GR.ditherChanged = fromMaybe False maybeDither /= dither } else do resetPreviewFunction guiComponents @@ -246,12 +248,13 @@ preview atomicModifyIORef' guiPreviewStateRef $ \ guiPreviewState' -> ( guiPreviewState' - { GR.maybeInFilePath = if invalidInFilePath then Nothing else Just inFilePath - , GR.maybeStartTime = if invalidStartTime then Nothing else Just startTime - , GR.maybeEndTime = if invalidEndTime then Nothing else Just endTime - , GR.maybeColorCount = if invalidColorCount then Nothing else Just colorCount - , GR.maybeDither = Just dither - , GR.loopRunning = True + { GR.maybeInFilePath = if invalidInFilePath then Nothing else Just inFilePath + , GR.maybeInFileLoadedAt = if invalidInFileLoadedAtChanged then Nothing else Just inFileLoadedAt + , GR.maybeStartTime = if invalidStartTime then Nothing else Just startTime + , GR.maybeEndTime = if invalidEndTime then Nothing else Just endTime + , GR.maybeColorCount = if invalidColorCount then Nothing else Just colorCount + , GR.maybeDither = Just dither + , GR.loopRunning = True } , () ) @@ -277,6 +280,7 @@ videoPreview , GR.inFileWidth , GR.inFileHeight , GR.inFilePathChanged + , GR.inFileLoadedAtChanged , GR.startTimeChanged , GR.endTimeChanged } @@ -288,8 +292,11 @@ videoPreview where sizePreviewAndWindow :: IO () sizePreviewAndWindow = do - let (previewWidth, previewHeight) = - getPreviewWidthAndHeight inFileWidth inFileHeight + (previewWidth, previewHeight) <- + getPreviewWidthAndHeight + window + inFileWidth + inFileHeight GI.Gtk.widgetSetSizeRequest window (doubleToInt32 previewWidth) @@ -313,11 +320,13 @@ videoPreview && ( playbinPosition < startTimeInNano || playbinPosition > endTimeInNano ) - let seekToStart = inFilePathChanged + let loadVideo = inFilePathChanged + || inFileLoadedAtChanged + let seekToStart = loadVideo || startTimeChanged || endTimeChanged || outOfBounds - when inFilePathChanged $ do + when loadVideo $ do void $ GI.Gst.elementSetState playbinElement GI.Gst.StateNull Data.GI.Base.Properties.setObjectPropertyString playbinElement @@ -387,12 +396,12 @@ firstAndLastFramePreview where handleChanges :: IO () handleChanges = do + (previewWidth, _) <- getPreviewWidthAndHeight window inFileWidth inFileHeight let firstAndLastFrameDirty = inFilePathChanged || startTimeChanged || colorCountChanged || ditherChanged let lastFrameDirty = not firstAndLastFrameDirty && endTimeChanged - let (previewWidth, _) = getPreviewWidthAndHeight inFileWidth inFileHeight let guiMakeFramePreviewFunctionArgs = GR.GuiMakeFramePreviewFunctionArgs { GR.inFilePath = inFilePath @@ -1131,22 +1140,35 @@ resetFirstAndLastFramePreview -> IO () resetFirstAndLastFramePreview _ = return () -resetWindow :: GR.GuiComponents -> IO () +resetWindow + :: GR.GuiComponents + -> IO () resetWindow GR.GuiComponents { GR.window + , GR.sidebarControlsPreviewbox , GR.mainPreviewBox , GR.imagesPreviewBox , GR.videoPreviewBox } = do + previewSize <- desiredPreviewSize window + sidebarWidth <- do + visible <- GI.Gtk.widgetGetVisible sidebarControlsPreviewbox + if visible + then + int32ToDouble + <$> GI.Gtk.widgetGetAllocatedWidth + sidebarControlsPreviewbox + else + return 1.0 GI.Gtk.widgetSetSizeRequest window - (doubleToInt32 $ desiredPreviewSize + 300.0) + (doubleToInt32 (previewSize + sidebarWidth)) (-1) GI.Gtk.widgetSetSizeRequest mainPreviewBox - (doubleToInt32 desiredPreviewSize) + (doubleToInt32 previewSize) (-1) GI.Gtk.widgetHide imagesPreviewBox GI.Gtk.widgetHide videoPreviewBox @@ -1309,25 +1331,25 @@ makeImagePreview } getPreviewWidthAndHeight - :: Double + :: GI.Gtk.Window -> Double - -> (Double, Double) -getPreviewWidthAndHeight inFileWidth inFileHeight = (previewWidth, previewHeight) - where - widthRatio :: Double - widthRatio = inFileWidth / inFileHeight - heightRatio :: Double - heightRatio = inFileHeight / inFileWidth - previewWidth :: Double - previewWidth = - if inFileWidth >= inFileHeight - then desiredPreviewSize - else (desiredPreviewSize / 2.0) * widthRatio - previewHeight :: Double - previewHeight = - if inFileWidth >= inFileHeight - then desiredPreviewSize * heightRatio - else desiredPreviewSize / 2.0 + -> Double + -> IO (Double, Double) +getPreviewWidthAndHeight + window + inFileWidth + inFileHeight + = do + previewSize <- desiredPreviewSize window + let previewWidth = + if inFileWidth >= inFileHeight + then previewSize + else previewSize * (inFileWidth / inFileHeight) + let previewHeight = + if inFileWidth >= inFileHeight + then previewSize * (inFileHeight / inFileWidth) + else previewSize + return (previewWidth, previewHeight) updatePreviewFrame :: String @@ -1347,3 +1369,43 @@ resetImage image = image (Just $ pack blankPreviewIcon) (enumToInt32 GI.Gtk.IconSizeButton) + +desiredPreviewSize + :: GI.Gtk.Window + -> IO Double +desiredPreviewSize + window + = do + let assumedScreenWidth = 1920.0 + let assumedPreviewSize = 700.0 + let margin = 100.0 + screenWidth <- do + screen <- GI.Gtk.windowGetScreen window + window' <- GI.Gtk.widgetGetWindow window + case window' of + Nothing -> + return assumedScreenWidth + (Just window'') -> do + monitorNumber <- GI.Gdk.screenGetMonitorAtWindow screen window'' + monitorRect <- GI.Gdk.screenGetMonitorGeometry screen monitorNumber + width <- int32ToDouble <$> GI.Gdk.getRectangleWidth monitorRect + return $ + if width < assumedScreenWidth + then width - margin + else width + -- Code for GTK >= 3.22. + -- Replace the above when dropping support for Ubuntu 16.04. + -- + --monitor' <- GI.Gdk.screenGetDisplay screen + -- >>= GI.Gdk.displayGetPrimaryMonitor + --case monitor' of + -- Nothing -> + -- return assumedScreenWidth + -- (Just monitor) -> do + -- monitorRect <- GI.Gdk.monitorGetGeometry monitor + -- width <- int32ToDouble <$> GI.Gdk.getRectangleWidth monitorRect + -- return $ + -- if width < assumedScreenWidth + -- then width - margin + -- else width + return (screenWidth * (assumedPreviewSize / assumedScreenWidth)) diff --git a/src/gui/GuiRecords.hs b/src/gui/GuiRecords.hs index 2f6bdd5..16f7e28 100644 --- a/src/gui/GuiRecords.hs +++ b/src/gui/GuiRecords.hs @@ -97,12 +97,13 @@ data GuiComponents = data GuiPreviewState = GuiPreviewState - { maybeInFilePath :: Maybe String - , maybeStartTime :: Maybe Double - , maybeEndTime :: Maybe Double - , maybeColorCount :: Maybe Double - , maybeDither :: Maybe Bool - , loopRunning :: Bool + { maybeInFilePath :: Maybe String + , maybeInFileLoadedAt :: Maybe Int + , maybeStartTime :: Maybe Double + , maybeEndTime :: Maybe Double + , maybeColorCount :: Maybe Double + , maybeDither :: Maybe Bool + , loopRunning :: Bool } data GuiInFileProperties = @@ -112,6 +113,7 @@ data GuiInFileProperties = , inFileDuration :: Double , inFileWidth :: Double , inFileHeight :: Double + , inFileLoadedAt :: Int } data GuiTextOverlayComponents = @@ -154,19 +156,20 @@ data GuiTextOverlayData = data GuiPreviewFunctionArgs = GuiPreviewFunctionArgs - { guiComponents :: GuiComponents - , inFilePath :: String - , startTime :: Double - , endTime :: Double - , colorCount :: Double - , inFileWidth :: Double - , inFileHeight :: Double - , dither :: Bool - , inFilePathChanged :: Bool - , startTimeChanged :: Bool - , endTimeChanged :: Bool - , colorCountChanged :: Bool - , ditherChanged :: Bool + { guiComponents :: GuiComponents + , inFilePath :: String + , startTime :: Double + , endTime :: Double + , colorCount :: Double + , inFileWidth :: Double + , inFileHeight :: Double + , dither :: Bool + , inFilePathChanged :: Bool + , inFileLoadedAtChanged :: Bool + , startTimeChanged :: Bool + , endTimeChanged :: Bool + , colorCountChanged :: Bool + , ditherChanged :: Bool } data GuiMakeFramePreviewFunctionArgs = @@ -199,12 +202,13 @@ data GuiSetOrResetFramePrevewFunctionArgs = defaultGuiPreviewState :: GuiPreviewState defaultGuiPreviewState = GuiPreviewState - { maybeInFilePath = Nothing - , maybeStartTime = Nothing - , maybeEndTime = Nothing - , maybeColorCount = Nothing - , maybeDither = Nothing - , loopRunning = False + { maybeInFilePath = Nothing + , maybeInFileLoadedAt = Nothing + , maybeStartTime = Nothing + , maybeEndTime = Nothing + , maybeColorCount = Nothing + , maybeDither = Nothing + , loopRunning = False } defaultGuiInFileProperties @@ -212,6 +216,7 @@ defaultGuiInFileProperties defaultGuiInFileProperties = GuiInFileProperties { inFileUri = "" + , inFileLoadedAt = 0 , inFileFps = 0.0 , inFileDuration = 0.0 , inFileWidth = 0.0 diff --git a/src/gui/Main.hs b/src/gui/Main.hs index e4b9b73..27503f0 100644 --- a/src/gui/Main.hs +++ b/src/gui/Main.hs @@ -10,6 +10,7 @@ , DuplicateRecordFields #-} +import System.Environment import System.Directory import System.FilePath import System.Process @@ -247,6 +248,8 @@ main = do GuiCapabilities.checkCapabilitiesAndNotify guiComponents GuiKeyboard.addKeyboardEventHandler guiComponents + handleCommandLineArguments guiComponents + GI.Gtk.main buildBuilder @@ -270,6 +273,29 @@ builderGetObject objectTypeClass builder objectId = do putStrLn $ "[ERROR] could not build " ++ objectId ++ "." GI.Gtk.unsafeCastTo objectTypeClass $ fromJust maybeObject +handleCommandLineArguments + :: GR.GuiComponents + -> IO () +handleCommandLineArguments + guiComponents@GR.GuiComponents + { GR.inFileChooserWidget + } + = do + args <- getArgs + case args of + [] -> return () + (filePath':_) -> do + filePath <- toAbsoluteUri filePath' + _ <- GI.Gtk.fileChooserSetFilename inFileChooserWidget filePath + _ <- GI.GLib.timeoutAdd + GI.GLib.PRIORITY_DEFAULT + 250 $ do + handleInFileChooserDialogReponse + guiComponents + (enumToInt32 GI.Gtk.ResponseTypeOk) + return False + return () + handleInFileChooserDialogReponse :: GR.GuiComponents -> Int32 @@ -335,10 +361,13 @@ handleInFileChooserDialogReponse inFilePath inFilePath' playableMetadataFps + epochTimestamp <- + getEpochTimestamp atomicModifyIORef' guiInFilePropertiesRef $ \ guiInFileProperties' -> ( guiInFileProperties' { GR.inFileUri = if fileExists then inFilePath' else inFilePath + , GR.inFileLoadedAt = epochTimestamp , GR.inFileFps = playableMetadataFps , GR.inFileDuration = playableMetadataDuration , GR.inFileWidth = playableMetadataWidth @@ -367,6 +396,7 @@ handleInFileChooserDialogReponse $ Data.Text.pack $ takeFileName inFilePath GI.Gtk.widgetShow sidebarControlsPreviewbox + return () _ -> resetOnFailure _ -> resetOnFailure resetOnFailure :: IO () @@ -965,12 +995,18 @@ handleUploadButtons handleGuiPreview :: GR.GuiComponents -> IO () -handleGuiPreview = GuiPreview.runGuiPreview +handleGuiPreview + = + GuiPreview.runGuiPreview handleWindow :: GR.GuiComponents -> IO () -handleWindow GR.GuiComponents { GR.window } = do +handleWindow + GR.GuiComponents + { GR.window + } + = do -- Setting the window to resizable false causes the video -- to load at its natural size. -- This workaround locks the window size which is required @@ -991,14 +1027,18 @@ handleWindow GR.GuiComponents { GR.window } = do openLocalFileWithDefaultProgram :: String -> IO () -openLocalFileWithDefaultProgram filePath = do +openLocalFileWithDefaultProgram + filePath + = do fileExists <- doesFileExist filePath when fileExists $ openUriWithDefaultProgram filePath openUriWithDefaultProgram :: String -> IO () -openUriWithDefaultProgram uri = do +openUriWithDefaultProgram + uri + = do maybeFileOpenCommand <- determineFileOpenCommand case maybeFileOpenCommand of Just fileOpenCommand -> diff --git a/src/lib/Gifcurry.hs b/src/lib/Gifcurry.hs index c433c77..0a5adb9 100644 --- a/src/lib/Gifcurry.hs +++ b/src/lib/Gifcurry.hs @@ -320,7 +320,7 @@ data SrtSubtitle = -- | The version number. versionNumber :: String -versionNumber = "6.0.0.0" +versionNumber = "6.0.1.0" -- | Specifies the default field values for 'TextOverlay'. defaultTextOverlay diff --git a/stack.yaml b/stack.yaml index 3993193..728430c 100644 --- a/stack.yaml +++ b/stack.yaml @@ -8,19 +8,19 @@ extra-deps: - aeson-1.4.2.0 - temporary-1.2.1.1 - yaml-0.8.26 - - haskell-gi-0.22.6 - - haskell-gi-base-0.22.2 - - gi-atk-2.0.20 - - gi-gobject-2.0.21 - - gi-gio-2.0.24 - - gi-glib-2.0.22 - - gi-pango-1.0.21 - - gi-gdk-3.0.21 - - gi-gdkpixbuf-2.0.22 - - gi-gtk-3.0.31 - - gi-cairo-1.0.22 - - gi-gstbase-1.0.21 - - gi-gst-1.0.21 - - gi-gstvideo-1.0.21 + - haskell-gi-0.23.0 + - haskell-gi-base-0.23.0 + - gi-atk-2.0.21 + - gi-gobject-2.0.22 + - gi-gio-2.0.25 + - gi-glib-2.0.23 + - gi-pango-1.0.22 + - gi-gdk-3.0.22 + - gi-gdkpixbuf-2.0.23 + - gi-gtk-3.0.32 + - gi-cairo-1.0.23 + - gi-gstbase-1.0.22 + - gi-gst-1.0.22 + - gi-gstvideo-1.0.22 resolver: lts-12.14 compiler-check: match-exact diff --git a/stack.yaml.lock b/stack.yaml.lock index 4bc0876..fd38895 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -19,110 +19,110 @@ packages: original: hackage: temporary-1.2.1.1 - completed: - hackage: yaml-0.8.26@sha256:160fd85a728c000312a196ec9ebd023e99513e8f7e47d4729a9acc00fc704ac1,5116 + hackage: yaml-0.8.26@sha256:0969487e1d5a6a530a92f02e52a702905d5929ccb7f77674ecc1d553d5fb848d,5142 pantry-tree: size: 2684 - sha256: 82dfd01473e24c2ea2c081392e04e8c7efa848b525462fd6c7a71c65c4899504 + sha256: 06d035d13bc88c56fb13fcd2c844bd054a41aaa57e73661a6f6aba686266847a original: hackage: yaml-0.8.26 - completed: - hackage: haskell-gi-0.22.6@sha256:a7d8f8c92109047489a22f5d0055e4e4bec0d4fa29a1c2264a54f2dfc3a117a3,4996 + hackage: haskell-gi-0.23.0@sha256:bf78485bdded4aa807dc570970c8a140099fc048f600b03ece69dd171c8fb873,5118 pantry-tree: size: 4346 - sha256: 0ec636b6b1e471186756caf8390e5994c4dfbd1c8eae5bb8cd88736fd09eb98c + sha256: d19f8cd2c1d0da9ab2b8f2d634f46fed667a71ce0a28efb8b20b42230fa4b3d4 original: - hackage: haskell-gi-0.22.6 + hackage: haskell-gi-0.23.0 - completed: - hackage: haskell-gi-base-0.22.2@sha256:e8d5cf0b4fada4914443f171b38c8b82924bbefca3196793b1622f5fa50adfb4,2308 + hackage: haskell-gi-base-0.23.0@sha256:6c90f3e710921e7884a86fb53bf4b4e50a178f61e3a4ea365a1aa9deba30a075,2341 pantry-tree: - size: 1663 - sha256: 6f85514d25d696f7389baa35cb34318e8cc896cad3244cb80d798bc71c5949f1 + size: 1734 + sha256: 34e47d409c51a684551dd82d33b6560c2669fde857766e93f1f45793213f7fac original: - hackage: haskell-gi-base-0.22.2 + hackage: haskell-gi-base-0.23.0 - completed: - hackage: gi-atk-2.0.20@sha256:1638d851cc7c63a9acaacca825cee676c67cad54939afa4db69f0e4ab91fc55d,6721 + hackage: gi-atk-2.0.21@sha256:0e1f319e26eb2d5de4cc1b4a31c7ce17a208e809d6d915f6e885b99f619d0f94,6791 pantry-tree: size: 355 - sha256: 6e11214e8b02bdde1d1fd718d1fe68c7b5736b11f97ec8e0cd4b67a9560c05d9 + sha256: 8dd7edfcc6f9d6c44570c25980fe2cdcd793a590b2d757ffb7f6fd010bb35c82 original: - hackage: gi-atk-2.0.20 + hackage: gi-atk-2.0.21 - completed: - hackage: gi-gobject-2.0.21@sha256:cbbc8e06e8e1446568054280d734dda6d8a888e166c60670fabddc4746835c36,9029 + hackage: gi-gobject-2.0.22@sha256:2e529981f39e5d399107d3468d4523badb8f856c926d09dcfa13a8e835f2c6cb,9347 pantry-tree: size: 364 - sha256: 6ca4fd8faaca179c5aa4d86631d9531da0065fa63a492445fec92de5962c2e21 + sha256: 95ffca9f1176776d363ea3330a2091a00240fbc4daff2a94af6761eeddc251c9 original: - hackage: gi-gobject-2.0.21 + hackage: gi-gobject-2.0.22 - completed: - hackage: gi-gio-2.0.24@sha256:f8840f15bcce9c280165f4a43b792e152fa5e806f4e8e86dcc5068363125dcae,21799 + hackage: gi-gio-2.0.25@sha256:11322bbed1688de35886949845fd1bf37c7a4e1020f19c1b60ce319f5f07655b,21869 pantry-tree: size: 359 - sha256: 08a2d203f3bbe18b53c349a84d26dfb7d2fd617a6907785aa2e770287de705dd + sha256: fcfaa95fa71364b94c520b7d5881b6296cec32bebe2cba8ea3b2a23e8192f678 original: - hackage: gi-gio-2.0.24 + hackage: gi-gio-2.0.25 - completed: - hackage: gi-glib-2.0.22@sha256:c05d4a446d5f642df1728697a8b5acf7ea2eccbdaff2484971a9ec1281b1c490,9486 + hackage: gi-glib-2.0.23@sha256:d931f5c5547e71689c8f4450c19b1a0240f1adfcf764c12fdeeb19b4adb31504,9558 pantry-tree: size: 358 - sha256: d422706d6a52a2a5062561da295c627d6070279fc258ec039a36efb2b8652dd9 + sha256: c6955d55c691358dfabea7290a01565f779db715677652565572c3d9bc561161 original: - hackage: gi-glib-2.0.22 + hackage: gi-glib-2.0.23 - completed: - hackage: gi-pango-1.0.21@sha256:7b293da6308c5cbe7d5898ab975cf8364f8556bfb86c40e4784ba1abd422249d,8073 + hackage: gi-pango-1.0.22@sha256:d415a3527698cb624fb724062b8f0a81b56bc40eff3d8b67450f083db86d3c7d,8147 pantry-tree: size: 360 - sha256: cc90f53fd7fa2f11fd897874e36d903f0af425e2e2550ed1d7c0865fe3b1d6ab + sha256: 61e2927c45a7a0fe209cd9b36348a112b59360f2c6c0d49f0f47066de90339c8 original: - hackage: gi-pango-1.0.21 + hackage: gi-pango-1.0.22 - completed: - hackage: gi-gdk-3.0.21@sha256:e830b15bf6eaeb623175d848df017653aa78e0ffad20d8f5a84336d2737bb026,8933 + hackage: gi-gdk-3.0.22@sha256:cfc6709c26c844aa2242ef579d84ceaa58703d226346ac80144ea68285b574e8,9003 pantry-tree: size: 355 - sha256: 6b0d6bc94131082e37ed04d7aee9074027b40882db15ddf475419406c1de72d4 + sha256: 505446ce942474fe01357693aeef668fc8c7493537040b94f377e2b448785644 original: - hackage: gi-gdk-3.0.21 + hackage: gi-gdk-3.0.22 - completed: - hackage: gi-gdkpixbuf-2.0.22@sha256:0b66b5490e7bc1054e8dc19c50c581ed54c1883338ce7cec2a6d435d629553b1,3760 + hackage: gi-gdkpixbuf-2.0.23@sha256:f08d95ddea4431978e872684af359ece52f241e00acdbfffade86211f0a49e47,3842 pantry-tree: size: 368 - sha256: cf798239321d722db26a8abe87c900b4bdeea6cade5301ea5bccc8064a0143b8 + sha256: 71b891d78fd2a1ac65f6ddaddbf3fbd664e72eb7ca0798f417fae2abc91f294a original: - hackage: gi-gdkpixbuf-2.0.22 + hackage: gi-gdkpixbuf-2.0.23 - completed: - hackage: gi-gtk-3.0.31@sha256:f65a442b0d08893847d04048d0d327eb13d2a7494dc6c58344b10569f76816c4,38616 + hackage: gi-gtk-3.0.32@sha256:767e73231987191832cca97df96243164bd02556167db8368fb6b57f43cfed1a,38896 pantry-tree: size: 359 - sha256: 5707c1e3cf4a749bc858446125ee2b0b71e47b3c995b04eb0f4c04c9f58bbc69 + sha256: 39485485d9e72829b099ac682fda98ace5e3624efbf67705b52ec4ba47a3564d original: - hackage: gi-gtk-3.0.31 + hackage: gi-gtk-3.0.32 - completed: - hackage: gi-cairo-1.0.22@sha256:aaec6b1f029a326fed6b6503c86d08f40e270bf232079ef33120d1007cdb1444,3653 + hackage: gi-cairo-1.0.23@sha256:e0015eada06b6c365c1dd5e7baddce56ed70fa6c9db415c22ac91c885d727ffb,3727 pantry-tree: size: 358 - sha256: 0c16d821b5ec0ca3ba4378999a10373b8c63f86a82228361a1571289766ca670 + sha256: df849fdea4733e665daf0b1c6af8d216097ff040b119ced6e0a48834d9eabee1 original: - hackage: gi-cairo-1.0.22 + hackage: gi-cairo-1.0.23 - completed: - hackage: gi-gstbase-1.0.21@sha256:0d08d7aad9fb261ed1ca05047e8d30e0354e6e8681e38b7b9dbd787819d8a8fa,4608 + hackage: gi-gstbase-1.0.22@sha256:65e5c684f2db1fe3e3739319aec5cf73e01ce2815c6b449787fccb12b0163137,4686 pantry-tree: size: 363 - sha256: d2cc88bdb477134adf08d13a4d39224909df32f6c9b11a187846fc0ec4a7dba4 + sha256: 33c3efd9136db929df01cc5de50437743ee9c05c033ac9f3e210ecb8728ae547 original: - hackage: gi-gstbase-1.0.21 + hackage: gi-gstbase-1.0.22 - completed: - hackage: gi-gst-1.0.21@sha256:6fb5aaa166a99d6147b927dc31d77a3336a97f09cdaf39483307f2f59dbe8089,12383 + hackage: gi-gst-1.0.22@sha256:173133e9c731e22e4113c55d97010bcadbefa24778181e723f110f905c3111c8,12453 pantry-tree: size: 357 - sha256: 97bb5624e534bdc0ea503c9be95d87928a0d08ca94ed9f5d62feb99eda1a1cf2 + sha256: c9b6d556e4c515531e8d63a3f15ddb00439b8430d78a2cc8684ef4a7a026732d original: - hackage: gi-gst-1.0.21 + hackage: gi-gst-1.0.22 - completed: - hackage: gi-gstvideo-1.0.21@sha256:4d3231fe308fc42dc26448cc669016631a73cbe7e6b417ad26bf491d8224a4e6,8921 + hackage: gi-gstvideo-1.0.22@sha256:024bb71bfc9436147646e6c7c1f2d248c36eaa5cd3c333aa777b478a31d32a65,9001 pantry-tree: size: 365 - sha256: 80190a7393d4bc40bbd1223e0109505d757a7acd0fb4b88a4278ee90c54699ce + sha256: eb77ede90c5ec1bcfb9f9b0fed6d7bf4ff1cfd66d729570978c9deb64746a943 original: - hackage: gi-gstvideo-1.0.21 + hackage: gi-gstvideo-1.0.22 snapshots: - completed: size: 504771