AhhhahsdjashdMerge branch 'main' of git.tebibyte.media:tomo/tomo
This commit is contained in:
commit
b62b846745
|
@ -45,6 +45,10 @@ func (broadcaster *Broadcaster[L]) ensure () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NoCookie is a cookie that does nothing when closed.
|
||||||
|
type NoCookie struct { }
|
||||||
|
func (NoCookie) Close () { }
|
||||||
|
|
||||||
type cookie[L any] struct {
|
type cookie[L any] struct {
|
||||||
id int
|
id int
|
||||||
broadcaster *Broadcaster[L]
|
broadcaster *Broadcaster[L]
|
||||||
|
@ -65,3 +69,17 @@ func (broadcaster *FuncBroadcaster) Broadcast () {
|
||||||
listener()
|
listener()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type multiCookie []Cookie
|
||||||
|
|
||||||
|
// MultiCookie creates a single cookie that, when closed, closes a list of other
|
||||||
|
// cookies.
|
||||||
|
func MultiCookie (cookies ...Cookie) Cookie {
|
||||||
|
return multiCookie(cookies)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cookies multiCookie) Close () {
|
||||||
|
for _, cookie := range cookies {
|
||||||
|
cookie.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -2,4 +2,4 @@ module git.tebibyte.media/tomo/tomo
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require golang.org/x/image v0.8.0
|
require golang.org/x/image v0.11.0
|
||||||
|
|
3
go.sum
3
go.sum
|
@ -3,6 +3,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/image v0.8.0 h1:agUcRXV/+w6L9ryntYYsF2x9fQTMd4T8fiiYXAVW6Jg=
|
golang.org/x/image v0.8.0 h1:agUcRXV/+w6L9ryntYYsF2x9fQTMd4T8fiiYXAVW6Jg=
|
||||||
golang.org/x/image v0.8.0/go.mod h1:PwLxp3opCYg4WR2WO9P0L6ESnsD6bLTWcw8zanLMVFM=
|
golang.org/x/image v0.8.0/go.mod h1:PwLxp3opCYg4WR2WO9P0L6ESnsD6bLTWcw8zanLMVFM=
|
||||||
|
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||||
|
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
@ -26,6 +28,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
|
|
@ -104,7 +104,7 @@ type Align int; const (
|
||||||
// Object is any obscreen object. Each object must be linked to a box, even if
|
// Object is any obscreen object. Each object must be linked to a box, even if
|
||||||
// it is that box.
|
// it is that box.
|
||||||
type Object interface {
|
type Object interface {
|
||||||
Box () Box
|
GetBox () Box
|
||||||
}
|
}
|
||||||
|
|
||||||
// Box is a basic styled box.
|
// Box is a basic styled box.
|
||||||
|
@ -238,7 +238,7 @@ type TextBox interface {
|
||||||
// SetSelectable sets whether or not the text content can be
|
// SetSelectable sets whether or not the text content can be
|
||||||
// highlighted/selected.
|
// highlighted/selected.
|
||||||
SetSelectable (bool)
|
SetSelectable (bool)
|
||||||
// SetDotColor sets the highlight color of the text selection.
|
// SetDotColor sets the highlight color of selected text.
|
||||||
SetDotColor (color.Color)
|
SetDotColor (color.Color)
|
||||||
// Select sets the text cursor or selection.
|
// Select sets the text cursor or selection.
|
||||||
Select (text.Dot)
|
Select (text.Dot)
|
||||||
|
|
|
@ -0,0 +1,288 @@
|
||||||
|
package theme
|
||||||
|
|
||||||
|
import "image"
|
||||||
|
import "git.tebibyte.media/tomo/tomo/data"
|
||||||
|
|
||||||
|
// IconSize represents the size of an icon.
|
||||||
|
type IconSize int; const (
|
||||||
|
IconSizeSmall IconSize = iota;
|
||||||
|
IconSizeMedium
|
||||||
|
IconSizeLarge
|
||||||
|
)
|
||||||
|
|
||||||
|
// Icon represents an icon ID.
|
||||||
|
type Icon int; const (
|
||||||
|
// --- Objects --- //
|
||||||
|
|
||||||
|
// files
|
||||||
|
IconFile Icon = iota
|
||||||
|
IconDirectory
|
||||||
|
IconDirectoryFull
|
||||||
|
|
||||||
|
// places
|
||||||
|
IconDownloads
|
||||||
|
IconPhotos
|
||||||
|
IconBooks
|
||||||
|
IconDocuments
|
||||||
|
IconRepositories
|
||||||
|
IconMusic
|
||||||
|
IconArchives
|
||||||
|
IconFonts
|
||||||
|
IconBinaries
|
||||||
|
IconVideos
|
||||||
|
Icon3DObjects
|
||||||
|
IconHistory
|
||||||
|
IconPreferences
|
||||||
|
|
||||||
|
// storage
|
||||||
|
IconStorage // generic
|
||||||
|
IconMagneticTape
|
||||||
|
IconFloppyDisk
|
||||||
|
IconHardDisk
|
||||||
|
IconSolidStateDrive
|
||||||
|
IconFlashDrive
|
||||||
|
IconMemoryCard
|
||||||
|
IconROMDisk
|
||||||
|
IconRAMDisk
|
||||||
|
IconCD
|
||||||
|
IconDVD
|
||||||
|
|
||||||
|
// network
|
||||||
|
IconNetwork // generic
|
||||||
|
IconLocalNetwork
|
||||||
|
IconInternet
|
||||||
|
IconEthernet
|
||||||
|
IconWireless
|
||||||
|
IconCell
|
||||||
|
IconBluetooth
|
||||||
|
IconRadio
|
||||||
|
|
||||||
|
// devices
|
||||||
|
IconDevice // generic
|
||||||
|
IconRouter
|
||||||
|
IconServer
|
||||||
|
IconDesktop
|
||||||
|
IconLaptop
|
||||||
|
IconTablet
|
||||||
|
IconPhone
|
||||||
|
IconWatch
|
||||||
|
IconCamera
|
||||||
|
|
||||||
|
// peripherals
|
||||||
|
IconPeripheral // generic
|
||||||
|
IconKeyboard
|
||||||
|
IconMouse
|
||||||
|
IconMonitor
|
||||||
|
IconWebcam
|
||||||
|
IconMicrophone
|
||||||
|
IconSpeaker
|
||||||
|
IconPenTablet
|
||||||
|
IconTrackpad
|
||||||
|
IconController
|
||||||
|
|
||||||
|
// i/o
|
||||||
|
IconPort // generic
|
||||||
|
IconEthernetPort
|
||||||
|
IconUSBPort
|
||||||
|
IconParallelPort
|
||||||
|
IconSerialPort
|
||||||
|
IconPS2Port
|
||||||
|
IconDisplayConnector
|
||||||
|
IconCGAPort
|
||||||
|
IconVGAPort
|
||||||
|
IconHDMIPort
|
||||||
|
IconDisplayPort
|
||||||
|
IconInfrared
|
||||||
|
|
||||||
|
// --- Actions --- //
|
||||||
|
|
||||||
|
// files
|
||||||
|
IconOpen
|
||||||
|
IconOpenIn
|
||||||
|
IconSave
|
||||||
|
IconSaveAs
|
||||||
|
IconPrints
|
||||||
|
IconNew
|
||||||
|
IconNewDirectory
|
||||||
|
IconDelete
|
||||||
|
IconRename
|
||||||
|
IconGetInformation
|
||||||
|
IconChangePermissions
|
||||||
|
IconRevert
|
||||||
|
|
||||||
|
// list management
|
||||||
|
IconAdd
|
||||||
|
IconRemove
|
||||||
|
IconAddBookmark
|
||||||
|
IconRemoveBookmark
|
||||||
|
IconAddFavorite
|
||||||
|
IconRemoveFavorite
|
||||||
|
|
||||||
|
// media
|
||||||
|
IconPlay
|
||||||
|
IconPause
|
||||||
|
IconStop
|
||||||
|
IconFastForward
|
||||||
|
IconRewind
|
||||||
|
IconToBeginning
|
||||||
|
IconToEnd
|
||||||
|
IconRecord
|
||||||
|
IconVolumeUp
|
||||||
|
IconVolumeDown
|
||||||
|
IconMute
|
||||||
|
|
||||||
|
// editing
|
||||||
|
IconUndo
|
||||||
|
IconRedo
|
||||||
|
IconCut
|
||||||
|
IconCopy
|
||||||
|
IconPaste
|
||||||
|
IconFind
|
||||||
|
IconReplace
|
||||||
|
IconSelectAll
|
||||||
|
IconSelectNone
|
||||||
|
IconIncrement
|
||||||
|
IconDecrement
|
||||||
|
|
||||||
|
// window management
|
||||||
|
IconClose
|
||||||
|
IconQuit
|
||||||
|
IconIconify
|
||||||
|
IconShade
|
||||||
|
IconMaximize
|
||||||
|
IconFullScreen
|
||||||
|
IconRestore
|
||||||
|
|
||||||
|
// view controls
|
||||||
|
IconExpand
|
||||||
|
IconContract
|
||||||
|
IconBack
|
||||||
|
IconForward
|
||||||
|
IconUp
|
||||||
|
IconDown
|
||||||
|
IconReload
|
||||||
|
IconZoomIn
|
||||||
|
IconZoomOut
|
||||||
|
IconZoomReset
|
||||||
|
IconMove
|
||||||
|
IconResize
|
||||||
|
IconGoTo
|
||||||
|
|
||||||
|
// tools
|
||||||
|
IconTransform
|
||||||
|
IconTranslate
|
||||||
|
IconRotate
|
||||||
|
IconScale
|
||||||
|
IconWarp
|
||||||
|
IconCornerPin
|
||||||
|
IconSelectRectangle
|
||||||
|
IconSelectEllipse
|
||||||
|
IconSelectLasso
|
||||||
|
IconSelectGeometric
|
||||||
|
IconSelectAuto
|
||||||
|
IconCrop
|
||||||
|
IconFill
|
||||||
|
IconGradient
|
||||||
|
IconPencil
|
||||||
|
IconBrush
|
||||||
|
IconEraser
|
||||||
|
IconText
|
||||||
|
IconEyedropper
|
||||||
|
|
||||||
|
// --- Status --- //
|
||||||
|
|
||||||
|
// dialogs
|
||||||
|
IconInformation
|
||||||
|
IconQuestion
|
||||||
|
IconWarning
|
||||||
|
IconError
|
||||||
|
IconCancel
|
||||||
|
IconOkay
|
||||||
|
|
||||||
|
// network
|
||||||
|
IconCellSignal0
|
||||||
|
IconCellSignal1
|
||||||
|
IconCellSignal2
|
||||||
|
IconCellSignal3
|
||||||
|
IconWirelessSignal0
|
||||||
|
IconWirelessSignal1
|
||||||
|
IconWirelessSignal2
|
||||||
|
IconWirelessSignal3
|
||||||
|
|
||||||
|
// power
|
||||||
|
IconBattery0
|
||||||
|
IconBattery1
|
||||||
|
IconBattery2
|
||||||
|
IconBattery3
|
||||||
|
IconBrightness0
|
||||||
|
IconBrightness1
|
||||||
|
IconBrightness2
|
||||||
|
IconBrightness3
|
||||||
|
|
||||||
|
// media
|
||||||
|
IconVolume0
|
||||||
|
IconVolume1
|
||||||
|
IconVolume2
|
||||||
|
IconVolume3
|
||||||
|
)
|
||||||
|
|
||||||
|
// Icon returns an image of the corresponding icon ID.
|
||||||
|
func (id Icon) Image (size IconSize) image.Image {
|
||||||
|
if current == nil { return image.Rect(0, 0, 16, 16) }
|
||||||
|
return current.Icon(id, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MimeIcon returns an icon corresponding to a MIME type. This must
|
||||||
|
// always return a non-nil value.
|
||||||
|
func MimeIcon (mime data.Mime, size IconSize) image.Image {
|
||||||
|
if current == nil { return image.Rect(0, 0, 16, 16) }
|
||||||
|
return current.MimeIcon(mime, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplicationIcon describes the icon of the application.
|
||||||
|
type ApplicationIcon struct {
|
||||||
|
// The name or ID of the application. If applicable, this should
|
||||||
|
// correspond to the file name (without the path or extension) of the
|
||||||
|
// icon on the system. This field is optional.
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Role describes what the application does. If a specific icon file
|
||||||
|
// cannot be found, a generic one is picked using this field.
|
||||||
|
Role ApplicationRole
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplicationRole describes what an application does.
|
||||||
|
type ApplicationRole int; const (
|
||||||
|
RoleUnknown ApplicationRole = iota
|
||||||
|
|
||||||
|
RoleWebBrowser
|
||||||
|
RoleMesssanger
|
||||||
|
RolePhone
|
||||||
|
RoleMail
|
||||||
|
|
||||||
|
RoleTerminalEmulator
|
||||||
|
RoleFileBrowser
|
||||||
|
RoleTextEditor
|
||||||
|
|
||||||
|
RoleDocumentViewer
|
||||||
|
RoleWordProcessor
|
||||||
|
RoleSpreadsheet
|
||||||
|
RoleSlideshow
|
||||||
|
RoleCalculator
|
||||||
|
|
||||||
|
RolePreferences
|
||||||
|
RoleProcessManager
|
||||||
|
RoleSystemInformation
|
||||||
|
RoleManual
|
||||||
|
|
||||||
|
RoleCamera
|
||||||
|
RoleImageViewer
|
||||||
|
RoleMediaPlayer
|
||||||
|
RoleImageEditor
|
||||||
|
RoleAudioEditor
|
||||||
|
RoleVideoEditor
|
||||||
|
|
||||||
|
RoleClock
|
||||||
|
RoleCalendar
|
||||||
|
RoleChecklist
|
||||||
|
)
|
|
@ -0,0 +1,85 @@
|
||||||
|
package theme
|
||||||
|
|
||||||
|
import "image"
|
||||||
|
import "git.tebibyte.media/tomo/tomo"
|
||||||
|
import "git.tebibyte.media/tomo/tomo/data"
|
||||||
|
import "git.tebibyte.media/tomo/tomo/event"
|
||||||
|
|
||||||
|
// Role describes the role of an object.
|
||||||
|
type Role struct {
|
||||||
|
// Package is an optional namespace field. If specified, it should be
|
||||||
|
// the package name or module name the object is from.
|
||||||
|
Package string
|
||||||
|
|
||||||
|
// Object specifies what type of object it is. For example:
|
||||||
|
// - TextInput
|
||||||
|
// - Table
|
||||||
|
// - Label
|
||||||
|
// - Dial
|
||||||
|
// This should correspond directly to the type name of the object.
|
||||||
|
Object string
|
||||||
|
|
||||||
|
// Variant is an optional field to be used when an object has one or
|
||||||
|
// more soft variants under one type. For example, an object "Slider"
|
||||||
|
// may have variations "horizontal" and "vertical".
|
||||||
|
Variant string
|
||||||
|
}
|
||||||
|
|
||||||
|
// R is shorthand for creating a Role structure.
|
||||||
|
func R (pack, object, variant string) Role {
|
||||||
|
return Role { Package: pack, Object: object, Variant: variant }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color represents a color ID.
|
||||||
|
type Color int; const (
|
||||||
|
ColorBackground Color = iota
|
||||||
|
ColorForeground
|
||||||
|
ColorRaised
|
||||||
|
ColorSunken
|
||||||
|
ColorAccent
|
||||||
|
)
|
||||||
|
|
||||||
|
// RGBA satisfies the color.Color interface.
|
||||||
|
func (id Color) RGBA () (r, g, b, a uint32) {
|
||||||
|
if current == nil { return }
|
||||||
|
return current.RGBA(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Theme is an object that can apply a visual style to different objects.
|
||||||
|
type Theme interface {
|
||||||
|
// Apply applies the theme to the given object, according to the given
|
||||||
|
// role. This may register event listeners with the given object;
|
||||||
|
// closing the returned cookie will remove them.
|
||||||
|
Apply (tomo.Object, Role) event.Cookie
|
||||||
|
|
||||||
|
// RGBA returns the RGBA values of the corresponding color ID.
|
||||||
|
RGBA (Color) (r, g, b, a uint32)
|
||||||
|
|
||||||
|
// Icon returns an image of the corresponding icon ID. This must always
|
||||||
|
// return a non-nil value.
|
||||||
|
Icon (Icon, IconSize) image.Image
|
||||||
|
|
||||||
|
// MimeIcon returns an icon corresponding to a MIME type. This must
|
||||||
|
// always return a non-nil value.
|
||||||
|
MimeIcon (data.Mime, IconSize) image.Image
|
||||||
|
|
||||||
|
// ApplicationIcon returns an icon corresponding to an application. This
|
||||||
|
// must always return a non-nil value.
|
||||||
|
ApplicationIcon (ApplicationIcon, IconSize) image.Image
|
||||||
|
}
|
||||||
|
|
||||||
|
var current Theme
|
||||||
|
|
||||||
|
// SetTheme sets the theme.
|
||||||
|
func SetTheme (theme Theme) {
|
||||||
|
current = theme
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply applies the current theme to the given object, according to the given
|
||||||
|
// role. This may register event listeners with the given object; closing the
|
||||||
|
// returned cookie will remove them.
|
||||||
|
func Apply (object tomo.Object, role Role) event.Cookie {
|
||||||
|
if current == nil { return event.NoCookie { } }
|
||||||
|
return current.Apply(object, role)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue