forked from Leak_Technologies/VideoTools
Compare commits
3 Commits
c81d540b0f
...
bec66816df
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bec66816df | ||
|
|
aba4d14f57 | ||
|
|
03b6804a9e |
|
|
@ -13,6 +13,28 @@ import (
|
|||
"github.com/gotk3/gotk3/gtk"
|
||||
)
|
||||
|
||||
const appCSS = `
|
||||
* {
|
||||
font-family: "Noto Sans", "Cantarell", "Sans";
|
||||
color: #E1EEFF;
|
||||
}
|
||||
window, GtkDrawingArea, box {
|
||||
background-color: #0B0F1A;
|
||||
}
|
||||
button {
|
||||
background: #171C2A;
|
||||
color: #E1EEFF;
|
||||
border-radius: 6px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
button:hover {
|
||||
background: #24314A;
|
||||
}
|
||||
label {
|
||||
color: #E1EEFF;
|
||||
}
|
||||
`
|
||||
|
||||
type pane struct {
|
||||
area *gtk.DrawingArea
|
||||
mpv *mpvembed.Client
|
||||
|
|
@ -42,6 +64,12 @@ func main() {
|
|||
grid.Attach(left.area, 0, 1, 1, 1)
|
||||
grid.Attach(right.area, 1, 1, 1, 1)
|
||||
|
||||
applyCSS()
|
||||
preferDark()
|
||||
|
||||
setupDragDest(left, win)
|
||||
setupDragDest(right, win)
|
||||
|
||||
win.Connect("destroy", func() {
|
||||
if left.mpv != nil {
|
||||
left.mpv.Destroy()
|
||||
|
|
@ -215,3 +243,50 @@ func getWindowID(w *gdk.Window) uint64 {
|
|||
func gdkWindowGetXID(w *gdk.Window) uint {
|
||||
return uint(w.GetXID())
|
||||
}
|
||||
|
||||
func applyCSS() {
|
||||
provider, err := gtk.CssProviderNew()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err := provider.LoadFromData(appCSS); err != nil {
|
||||
return
|
||||
}
|
||||
screen, err := gdk.ScreenGetDefault()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
gtk.AddProviderForScreen(screen, provider, gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
||||
}
|
||||
|
||||
func preferDark() {
|
||||
if settings, err := gtk.SettingsGetDefault(); err == nil && settings != nil {
|
||||
_ = settings.SetProperty("gtk-application-prefer-dark-theme", true)
|
||||
}
|
||||
}
|
||||
|
||||
func setupDragDest(p *pane, win *gtk.Window) {
|
||||
// Accept URI drops
|
||||
p.area.DragDestSet(gtk.DEST_DEFAULT_ALL, []gtk.TargetEntry{gtk.TargetEntry{}} /* dummy */, gdk.ACTION_COPY)
|
||||
p.area.Connect("drag-data-received", func(_ *gtk.DrawingArea, ctx *gdk.DragContext, x, y int, data *gtk.SelectionData, info uint, t uint32) {
|
||||
uris := data.GetURIs()
|
||||
if len(uris) == 0 {
|
||||
return
|
||||
}
|
||||
// Take first URI
|
||||
if path := uriToPath(uris[0]); path != "" {
|
||||
loadIntoPane(p, path)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func uriToPath(u string) string {
|
||||
if u == "" {
|
||||
return ""
|
||||
}
|
||||
// text/uri-list format: file:///path or path\n
|
||||
if len(u) >= 7 && u[:7] == "file://" {
|
||||
u = u[7:]
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
|
|
|||
20
main.go
20
main.go
|
|
@ -4,15 +4,12 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"io"
|
||||
"math"
|
||||
"net/url"
|
||||
"os"
|
||||
|
|
@ -42,7 +39,6 @@ import (
|
|||
"git.leaktechnologies.dev/stu/VT_Player/internal/queue"
|
||||
"git.leaktechnologies.dev/stu/VT_Player/internal/ui"
|
||||
"git.leaktechnologies.dev/stu/VT_Player/internal/utils"
|
||||
"github.com/hajimehoshi/oto"
|
||||
)
|
||||
|
||||
// Module describes a high level tool surface that gets a tile on the menu.
|
||||
|
|
@ -2034,7 +2030,6 @@ func runGUI() {
|
|||
a.Settings().SetTheme(&ui.MonoTheme{})
|
||||
logging.Debug(logging.CatUI, "created fyne app: %#v", a)
|
||||
w := a.NewWindow("VT Player")
|
||||
state.window = w
|
||||
if icon := utils.LoadAppIcon(); icon != nil {
|
||||
a.SetIcon(icon)
|
||||
w.SetIcon(icon)
|
||||
|
|
@ -3948,21 +3943,6 @@ func (s *appState) showFrameManual(path string, img *canvas.Image) {
|
|||
}
|
||||
|
||||
func (s *appState) captureCoverFromCurrent() (string, error) {
|
||||
// If we have a play session active, capture the current playing frame
|
||||
if s.playSess != nil && s.playSess.img != nil && s.playSess.img.Image != nil {
|
||||
dest := filepath.Join(os.TempDir(), fmt.Sprintf("videotools-cover-%d.png", time.Now().UnixNano()))
|
||||
f, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
if err := png.Encode(f, s.playSess.img.Image); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return dest, nil
|
||||
}
|
||||
|
||||
// Otherwise use the current preview frame
|
||||
if s.currentFrame == "" {
|
||||
return "", fmt.Errorf("no frame available")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package mpvembed
|
|||
#cgo pkg-config: mpv
|
||||
#include <mpv/client.h>
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
|
||||
static inline const char* mpv_errstr(int err) { return mpv_error_string(err); }
|
||||
*/
|
||||
|
|
@ -21,6 +22,8 @@ type Client struct {
|
|||
|
||||
// New creates a new mpv client.
|
||||
func New() (*Client, error) {
|
||||
// Ensure numeric locale is C to satisfy mpv.
|
||||
C.setlocale(C.int(C.LC_NUMERIC), C.CString("C"))
|
||||
h := C.mpv_create()
|
||||
if h == nil {
|
||||
return nil, errors.New("mpv_create returned nil")
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user