Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ module servercommander
go 1.23.5

require fyne.io/fyne/v2 v2.4.5

replace fyne.io/fyne/v2 => ./third_party/fyne
3 changes: 3 additions & 0 deletions src/ui/console_server.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build !desktop
// +build !desktop

package ui

import (
Expand Down
3 changes: 3 additions & 0 deletions src/ui/desktop_console.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build desktop
// +build desktop

package ui

import (
Expand Down
90 changes: 90 additions & 0 deletions third_party/fyne/app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package app

import (
"fmt"
"net/url"
"sync"

"fyne.io/fyne/v2"
)

// New returns a minimal stub implementation of fyne.App so builds can succeed
// in environments where the full dependency graph is unavailable.
func New() fyne.App {
return &stubApp{}
}

type stubApp struct {
mu sync.Mutex
windows []*stubWindow
}

func (a *stubApp) NewWindow(title string) fyne.Window {
win := &stubWindow{title: title, app: a}
a.mu.Lock()
a.windows = append(a.windows, win)
a.mu.Unlock()
return win
}

func (a *stubApp) Run() {
// No event loop in the stub implementation.
}

func (a *stubApp) QueueUpdate(fn func()) {
if fn != nil {
fn()
}
}

func (a *stubApp) OpenURL(u *url.URL) error {
if u == nil {
return fmt.Errorf("nil url provided")
}
// The stub just acknowledges the request.
return nil
}

type stubWindow struct {
app *stubApp
title string
size fyne.Size
content fyne.CanvasObject
closeIntercept func()
}

func (w *stubWindow) SetMaster() {}

func (w *stubWindow) SetFixedSize(bool) {}

func (w *stubWindow) Resize(size fyne.Size) {
w.size = size
}

func (w *stubWindow) CenterOnScreen() {}

func (w *stubWindow) SetCloseIntercept(fn func()) {
w.closeIntercept = fn
}

func (w *stubWindow) Show() {}

func (w *stubWindow) Close() {
if w.closeIntercept != nil {
w.closeIntercept()
}
}

func (w *stubWindow) SetContent(obj fyne.CanvasObject) {
w.content = obj
}

func (w *stubWindow) Canvas() fyne.Canvas {
return stubCanvas{}
}

type stubCanvas struct{}

func (stubCanvas) MinSize() fyne.Size {
return fyne.Size{}
}
37 changes: 37 additions & 0 deletions third_party/fyne/canvas/text.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package canvas

import (
"image/color"

"fyne.io/fyne/v2"
)

// Text is a minimal representation of a canvas text element.
type Text struct {
Text string
Color color.Color
TextSize float32
TextStyle fyne.TextStyle
Alignment fyne.TextAlign
}

// NewText creates a new canvas text instance.
func NewText(text string, clr color.Color) *Text {
return &Text{Text: text, Color: clr, TextSize: 12}
}

// MinSize returns a naive size estimation for the text.
func (t *Text) MinSize() fyne.Size {
width := float32(len(t.Text)) * 7
if width == 0 {
width = 1
}
height := t.TextSize
if height == 0 {
height = 12
}
return fyne.NewSize(width, height)
}

// Refresh does nothing in the stub implementation.
func (t *Text) Refresh() {}
92 changes: 92 additions & 0 deletions third_party/fyne/container/container.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package container

import "fyne.io/fyne/v2"

// Container is a simple grouping of canvas objects.
type Container struct {
Objects []fyne.CanvasObject
size fyne.Size
}

// MinSize returns a naive size estimation based on contained objects.
func (c *Container) MinSize() fyne.Size {
if c == nil {
return fyne.Size{}
}
if c.size != (fyne.Size{}) {
return c.size
}
var width, height float32
for _, obj := range c.Objects {
if obj == nil {
continue
}
sz := obj.MinSize()
if sz.Width > width {
width = sz.Width
}
height += sz.Height
}
return fyne.NewSize(width, height)
}

// SetMinSize hints the container size.
func (c *Container) SetMinSize(size fyne.Size) {
if c != nil {
c.size = size
}
}

// NewVScroll wraps content inside a scroll container.
func NewVScroll(content fyne.CanvasObject) *Scroll {
return &Scroll{Content: content}
}

// NewHBox returns a container laid out horizontally.
func NewHBox(objects ...fyne.CanvasObject) *Container {
return &Container{Objects: append([]fyne.CanvasObject(nil), objects...)}
}

// NewBorder arranges objects around a center element.
func NewBorder(top, bottom, left, right, center fyne.CanvasObject) *Container {
objs := []fyne.CanvasObject{center, top, bottom, left, right}
return &Container{Objects: objs}
}

// NewCenter centres a single object.
func NewCenter(object fyne.CanvasObject) *Container {
return &Container{Objects: []fyne.CanvasObject{object}}
}

// Scroll represents a vertical scroll container.
type Scroll struct {
Content fyne.CanvasObject
size fyne.Size
}

// MinSize returns the stored minimum size.
func (s *Scroll) MinSize() fyne.Size {
if s == nil {
return fyne.Size{}
}
if s.size != (fyne.Size{}) {
return s.size
}
if s.Content == nil {
return fyne.Size{}
}
return s.Content.MinSize()
}

// SetMinSize stores a requested minimum size.
func (s *Scroll) SetMinSize(size fyne.Size) {
if s != nil {
s.size = size
}
}

// ScrollToBottom is a no-op in the stub implementation.
func (s *Scroll) ScrollToBottom() {}

// ScrollToTop is a no-op in the stub implementation.
func (s *Scroll) ScrollToTop() {}
3 changes: 3 additions & 0 deletions third_party/fyne/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module fyne.io/fyne/v2

go 1.20
10 changes: 10 additions & 0 deletions third_party/fyne/layout/spacer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package layout

import "fyne.io/fyne/v2"

type spacer struct{}

func (s *spacer) MinSize() fyne.Size { return fyne.Size{} }

// NewSpacer returns a placeholder object used to align widgets.
func NewSpacer() fyne.CanvasObject { return &spacer{} }
18 changes: 18 additions & 0 deletions third_party/fyne/theme/theme.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package theme

import "image/color"

// ForegroundColor returns a generic foreground colour.
func ForegroundColor() color.Color {
return color.NRGBA{R: 0x22, G: 0x22, B: 0x22, A: 0xff}
}

// PrimaryColor returns a highlight colour.
func PrimaryColor() color.Color {
return color.NRGBA{R: 0x21, G: 0x6c, B: 0xff, A: 0xff}
}

// BackgroundColor returns a generic background colour.
func BackgroundColor() color.Color {
return color.NRGBA{R: 0xf0, G: 0xf0, B: 0xf0, A: 0xff}
}
123 changes: 123 additions & 0 deletions third_party/fyne/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package fyne

import "net/url"

// App represents a graphical application instance.
type App interface {
NewWindow(title string) Window
Run()
QueueUpdate(func())
OpenURL(*url.URL) error
}

// Window describes a top-level user interface window.
type Window interface {
SetMaster()
SetFixedSize(bool)
Resize(Size)
CenterOnScreen()
SetCloseIntercept(func())
Show()
Close()
SetContent(CanvasObject)
Canvas() Canvas
}

// Canvas represents a drawable surface.
type Canvas interface{}

// CanvasObject is any drawable UI element.
type CanvasObject interface {
MinSize() Size
}

// Widget is any interactive canvas object that can render itself.
type Widget interface {
CanvasObject
CreateRenderer() WidgetRenderer
}

// WidgetRenderer draws a widget.
type WidgetRenderer interface {
Layout(Size)
MinSize() Size
Refresh()
Destroy()
Objects() []CanvasObject
}

// Size represents a width/height pair.
type Size struct {
Width float32
Height float32
}

// NewSize constructs a Size instance.
func NewSize(width, height float32) Size {
return Size{Width: width, Height: height}
}

// Position represents a point in 2D space.
type Position struct {
X float32
Y float32
}

// PointEvent describes a pointer interaction event.
type PointEvent struct {
AbsolutePosition Position
}

// TextStyle configures textual rendering options.
type TextStyle struct {
Bold bool
Italic bool
Monospace bool
}

// TextWrap controls wrapping behaviour.
type TextWrap int

const (
TextWrapOff TextWrap = iota
TextWrapBreak
TextWrapWord
)

// TextAlign controls textual alignment.
type TextAlign int

const (
TextAlignLeading TextAlign = iota
TextAlignCenter
TextAlignTrailing
)

// Menu represents a pop-up menu structure.
type Menu struct {
Label string
Items []*MenuItem
}

// MenuItem is a single selectable menu item.
type MenuItem struct {
Label string
Action func()
}

// NewMenu constructs a new menu.
func NewMenu(label string, items ...*MenuItem) *Menu {
return &Menu{Label: label, Items: items}
}

// NewMenuItem constructs a new menu item.
func NewMenuItem(label string, action func()) *MenuItem {
return &MenuItem{Label: label, Action: action}
}

// Activate triggers the menu item's action.
func (m *MenuItem) Activate() {
if m != nil && m.Action != nil {
m.Action()
}
}
Loading