Requesting solution or support for vector-based option to replace the remaining PNGs. (Combobox and Checkbox)
I have gone through and reworked the demo resources.go file to be able to use a theme with the colors defined at the top. (I may move this to a config file later.) Now, I am to the part where I have a handful of images left that I cannot seem to replace. So, I would like to request either (1) Support for SVG, as Egitengine does support Vector graphics or (2) some other option that can be used in place of the loadGraphicImages
for the widget.CheckboxGraphicImage
properties and the comboButtonResources.graphic
.
This function is provided for quick reference.
I have put comments next to the properties I was able to to figure out. There are ?
next to ones I could not.
package main
import (
"image/color"
"strconv"
"github.com/ebitenui/ebitenui/image"
"github.com/ebitenui/ebitenui/widget"
"golang.org/x/image/font"
)
/*
Fresca:
primaryColor = color.NRGBA{R: 0x07, G: 0x68, B: 0x9F, A: 0xff}
secondaryColor = color.NRGBA{R: 0xC9, G: 0xD6, B: 0xDF, A: 0xff}
successColor = color.NRGBA{R: 0x11, G: 0xD3, B: 0xBC, A: 0xff}
dangerColor = color.NRGBA{R: 0xF6, G: 0x72, B: 0x80, A: 0xff}
infoColor = color.NRGBA{R: 0xA2, G: 0xD5, B: 0xF2, A: 0xff}
warningColor = color.NRGBA{R: 0xFF, G: 0x7E, B: 0x67, A: 0xff}
lightColor = color.NRGBA{R: 0xFA, G: 0xFA, B: 0xFA, A: 0xff}
darkColor = color.NRGBA{R: 0x4E, G: 0x4E, B: 0x4E, A: 0xff}
Greyson:
primaryColor = color.NRGBA{R: 0x2f, G: 0x3c, B: 0x48, A: 0xff}
secondaryColor = color.NRGBA{R: 0x6f, G: 0x7f, B: 0x8c, A: 0xff}
successColor = color.NRGBA{R: 0x3e, G: 0x4d, B: 0x59, A: 0xff}
dangerColor = color.NRGBA{R: 0xcc, G: 0x33, B: 0x0d, A: 0xff}
infoColor = color.NRGBA{R: 0x5c, G: 0x8f, B: 0x94, A: 0xff}
warningColor = color.NRGBA{R: 0x6e, G: 0x9f, B: 0xa5, A: 0xff}
lightColor = color.NRGBA{R: 0xec, G: 0xee, B: 0xec, A: 0xff}
darkColor = color.NRGBA{R: 0x1e, G: 0x2b, B: 0x37, A: 0xff}
Hootstrap:
primaryColor = color.NRGBA{R: 0x52, G: 0x80, B: 0x78, A: 0xff}
secondaryColor = color.NRGBA{R: 0xee, G: 0xd7, B: 0x5a, A: 0xff}
successColor = color.NRGBA{R: 0xFE, G: 0xC1, B: 0x00, A: 0xff}
dangerColor = color.NRGBA{R: 0x70, G: 0x3B, B: 0x3B, A: 0xff}
infoColor = color.NRGBA{R: 0x63, G: 0xe7, B: 0x92, A: 0xff}
warningColor = color.NRGBA{R: 0xFF, G: 0xE8, B: 0x69, A: 0xff}
lightColor = color.NRGBA{R: 0xFD, G: 0xFB, B: 0xF7, A: 0xff}
darkColor = color.NRGBA{R: 0x55, G: 0x55, B: 0x55, A: 0xff}
*/
var (
primaryColor = color.NRGBA{R: 0x2f, G: 0x3c, B: 0x48, A: 0xff}
secondaryColor = color.NRGBA{R: 0x6f, G: 0x7f, B: 0x8c, A: 0xff}
successColor = color.NRGBA{R: 0x3e, G: 0x4d, B: 0x59, A: 0xff}
dangerColor = color.NRGBA{R: 0xcc, G: 0x33, B: 0x0d, A: 0xff}
infoColor = color.NRGBA{R: 0x5c, G: 0x8f, B: 0x94, A: 0xff}
warningColor = color.NRGBA{R: 0x6e, G: 0x9f, B: 0xa5, A: 0xff}
lightColor = color.NRGBA{R: 0xec, G: 0xee, B: 0xec, A: 0xff}
darkColor = color.NRGBA{R: 0x1e, G: 0x2b, B: 0x37, A: 0xff}
primarySelectedColor = darkenColor(primaryColor, 0.2)
secondarySelectedColor = darkenColor(secondaryColor, 0.2)
primaryHoverColor = lightenColor(primaryColor, 0.2)
secondaryHoverColor = lightenColor(secondaryColor, 0.2)
lightOffsetColor = darkenColor(lightColor, 0.03)
primaryLightColor = lightenColor(primaryColor, 0.70)
primaryHoverLightColor = lightenColor(primaryColor, 0.50)
primaryColor9 = image.NewNineSliceColor(primaryColor)
secondaryColor9 = image.NewNineSliceColor(secondaryColor)
successColor9 = image.NewNineSliceColor(successColor)
dangerColor9 = image.NewNineSliceColor(dangerColor)
infoColor9 = image.NewNineSliceColor(infoColor)
warningColor9 = image.NewNineSliceColor(warningColor)
lightColor9 = image.NewNineSliceColor(lightColor)
darkColor9 = image.NewNineSliceColor(darkColor)
primarySelectedColor9 = image.NewNineSliceColor(primarySelectedColor)
secondarySelectedColor9 = image.NewNineSliceColor(secondarySelectedColor)
primaryHoverColor9 = image.NewNineSliceColor(primaryHoverColor)
secondaryHoverColor9 = image.NewNineSliceColor(secondaryHoverColor)
lightOffsetColor9 = image.NewNineSliceColor(lightOffsetColor)
primaryLightColor9 = image.NewNineSliceColor(primaryLightColor)
primaryHoverLightColor9 = image.NewNineSliceColor(primaryHoverColor)
)
func darkenColor(c color.NRGBA, percent float64) color.NRGBA {
r := uint8(float64(c.R) * (1 - percent))
g := uint8(float64(c.G) * (1 - percent))
b := uint8(float64(c.B) * (1 - percent))
return color.NRGBA{R: r, G: g, B: b, A: c.A}
}
func lightenColor(c color.NRGBA, percent float64) color.NRGBA {
r := uint8(float64(c.R) + (float64(0xff-c.R) * percent))
g := uint8(float64(c.G) + (float64(0xff-c.G) * percent))
b := uint8(float64(c.B) + (float64(0xff-c.B) * percent))
return color.NRGBA{R: r, G: g, B: b, A: c.A}
}
type uiResources struct {
fonts *fonts
background *image.NineSlice
separatorColor color.Color
text *textResources
button *buttonResources
label *labelResources
checkbox *checkboxResources
comboButton *comboButtonResources
list *listResources
slider *sliderResources
progressBar *progressBarResources
panel *panelResources
tabBook *tabBookResources
header *headerResources
textInput *textInputResources
textArea *textAreaResources
toolTip *toolTipResources
}
type textResources struct {
idleColor color.Color
disabledColor color.Color
face font.Face
titleFace font.Face
bigTitleFace font.Face
smallFace font.Face
}
type buttonResources struct {
image *widget.ButtonImage
text *widget.ButtonTextColor
face font.Face
padding widget.Insets
}
type checkboxResources struct {
image *widget.ButtonImage
graphic *widget.CheckboxGraphicImage
spacing int
}
type labelResources struct {
text *widget.LabelColor
face font.Face
}
type comboButtonResources struct {
image *widget.ButtonImage
text *widget.ButtonTextColor
face font.Face
graphic *widget.ButtonImageImage
padding widget.Insets
}
type listResources struct {
image *widget.ScrollContainerImage
track *widget.SliderTrackImage
trackPadding widget.Insets
handle *widget.ButtonImage
handleSize int
face font.Face
entry *widget.ListEntryColor
entryPadding widget.Insets
}
type sliderResources struct {
trackImage *widget.SliderTrackImage
handle *widget.ButtonImage
handleSize int
}
type progressBarResources struct {
trackImage *widget.ProgressBarImage
fillImage *widget.ProgressBarImage
}
type panelResources struct {
image *image.NineSlice
titleBar *image.NineSlice
padding widget.Insets
}
type tabBookResources struct {
buttonFace font.Face
buttonText *widget.ButtonTextColor
buttonPadding widget.Insets
}
type headerResources struct {
background *image.NineSlice
padding widget.Insets
face font.Face
color color.Color
}
type textInputResources struct {
image *widget.TextInputImage
padding widget.Insets
face font.Face
color *widget.TextInputColor
}
type textAreaResources struct {
image *widget.ScrollContainerImage
track *widget.SliderTrackImage
trackPadding widget.Insets
handle *widget.ButtonImage
handleSize int
face font.Face
entryPadding widget.Insets
}
type toolTipResources struct {
background *image.NineSlice
padding widget.Insets
face font.Face
color color.Color
}
func newUIResources() (*uiResources, error) {
// background := lightColor
fonts, err := loadFonts()
if err != nil {
return nil, err
}
button, err := newButtonResources(fonts)
if err != nil {
return nil, err
}
checkbox, err := newCheckboxResources()
if err != nil {
return nil, err
}
comboButton, err := newComboButtonResources(fonts)
if err != nil {
return nil, err
}
list, err := newListResources(fonts)
if err != nil {
return nil, err
}
slider, err := newSliderResources()
if err != nil {
return nil, err
}
progressBar, err := newProgressBarResources()
if err != nil {
return nil, err
}
panel, err := newPanelResources()
if err != nil {
return nil, err
}
tabBook, err := newTabBookResources(fonts)
if err != nil {
return nil, err
}
header, err := newHeaderResources(fonts)
if err != nil {
return nil, err
}
textInput, err := newTextInputResources(fonts)
if err != nil {
return nil, err
}
textArea, err := newTextAreaResources(fonts)
if err != nil {
return nil, err
}
toolTip, err := newToolTipResources(fonts)
if err != nil {
return nil, err
}
return &uiResources{
fonts: fonts,
background: lightColor9,
separatorColor: secondaryColor,
text: &textResources{
idleColor: primaryColor,
disabledColor: darkColor,
face: fonts.face,
titleFace: fonts.titleFace,
bigTitleFace: fonts.bigTitleFace,
smallFace: fonts.toolTipFace,
},
button: button,
label: newLabelResources(fonts),
checkbox: checkbox,
comboButton: comboButton,
list: list,
slider: slider,
panel: panel,
tabBook: tabBook,
header: header,
textInput: textInput,
toolTip: toolTip,
textArea: textArea,
progressBar: progressBar,
}, nil
}
func newButtonResources(fonts *fonts) (*buttonResources, error) {
i := &widget.ButtonImage{
Idle: primaryColor9, // button background
Hover: primaryHoverColor9, // button hover background
Pressed: infoColor9, // active selected button background
PressedHover: primaryLightColor9, // button click background
Disabled: secondaryColor9,
}
return &buttonResources{
image: i,
text: &widget.ButtonTextColor{
Idle: lightColor, // button text color
Disabled: primaryLightColor,
},
face: fonts.face,
padding: widget.Insets{
Left: 30,
Right: 30,
},
}, nil
}
func newCheckboxResources() (*checkboxResources, error) {
// TODO: Replace images
checked, err := loadGraphicImages("assets/graphics/checkbox-checked-idle.png", "assets/graphics/checkbox-checked-disabled.png")
if err != nil {
return nil, err
}
unchecked, err := loadGraphicImages("assets/graphics/checkbox-unchecked-idle.png", "assets/graphics/checkbox-unchecked-disabled.png")
if err != nil {
return nil, err
}
greyed, err := loadGraphicImages("assets/graphics/checkbox-greyed-idle.png", "assets/graphics/checkbox-greyed-disabled.png")
if err != nil {
return nil, err
}
// checkbox toggle switch button
return &checkboxResources{
image: &widget.ButtonImage{
Idle: lightColor9, // checkbox main background
Hover: primaryLightColor9, // checkbox hover background
Pressed: lightColor9, // checkbox click background
Disabled: secondaryColor9,
},
graphic: &widget.CheckboxGraphicImage{
Checked: checked, // TODO: Replace
Unchecked: unchecked, // TODO: Replace
Greyed: greyed, // TODO: Replace
},
spacing: 10,
}, nil
}
func newLabelResources(fonts *fonts) *labelResources {
return &labelResources{
text: &widget.LabelColor{
Idle: primaryColor,
Disabled: secondaryColor,
},
face: fonts.face,
}
}
// Select input dropdown
func newComboButtonResources(fonts *fonts) (*comboButtonResources, error) {
i := &widget.ButtonImage{
Idle: lightColor9, // main select input background
Hover: primaryLightColor9, // main select input hover
Pressed: lightColor9, // main select input click
Disabled: secondaryColor9,
}
// TODO: Replace images
arrowDown, err := loadGraphicImages("assets/graphics/fast-arrow-down.png", "assets/graphics/fast-arrow-down.png")
if err != nil {
return nil, err
}
return &comboButtonResources{
image: i,
text: &widget.ButtonTextColor{
Idle: primaryColor,
Disabled: secondaryColor,
},
face: fonts.face,
graphic: arrowDown, // TODO: replace
padding: widget.Insets{
Left: 20,
Right: 10,
},
}, nil
}
func newListResources(fonts *fonts) (*listResources, error) {
return &listResources{
image: &widget.ScrollContainerImage{ // scroll bar container
Idle: lightColor9,
Disabled: secondaryColor9,
Mask: dangerColor9, // not sure what this is yet
},
track: &widget.SliderTrackImage{ // The scroll bar
Idle: secondaryColor9,
Hover: secondaryHoverColor9,
Disabled: secondarySelectedColor9,
},
trackPadding: widget.Insets{
Top: 2, // padding of the handle on the bar
Bottom: 2,
},
handle: &widget.ButtonImage{
Idle: primarySelectedColor9, // color of idle handle
Hover: secondaryHoverColor9, // scroll bar handle hover
Pressed: primarySelectedColor9, // scroll bar handle click
Disabled: secondaryColor9,
},
handleSize: 5,
face: fonts.face,
entry: &widget.ListEntryColor{
Unselected: primaryColor,
DisabledUnselected: secondaryColor,
Selected: lightColor, // selected and active of text
DisabledSelected: secondarySelectedColor,
SelectedBackground: successColor, // seclected and active of box
DisabledSelectedBackground: darkColor,
FocusedBackground: primaryLightColor, // box of hover
SelectedFocusedBackground: primarySelectedColor,
},
entryPadding: widget.Insets{
Left: 30,
Right: 30,
Top: 2,
Bottom: 2,
},
}, nil
}
func newSliderResources() (*sliderResources, error) {
return &sliderResources{
trackImage: &widget.SliderTrackImage{
Idle: lightColor9,
Hover: secondaryHoverColor9,
Disabled: secondaryColor9,
},
handle: &widget.ButtonImage{
Idle: primaryColor9,
Hover: primaryHoverColor9,
Pressed: primarySelectedColor9,
Disabled: secondaryColor9,
},
handleSize: 6,
}, nil
}
func newProgressBarResources() (*progressBarResources, error) {
return &progressBarResources{
trackImage: &widget.ProgressBarImage{
Idle: lightColor9, // Progress bar empty background
Hover: primaryHoverColor9, // ?
Disabled: secondaryColor9, // ?
},
fillImage: &widget.ProgressBarImage{
Idle: primaryLightColor9, // bar of progress bar
Hover: primaryHoverLightColor9, // ?
Disabled: secondaryColor9, // ?
},
}, nil
}
func newPanelResources() (*panelResources, error) {
return &panelResources{
image: lightOffsetColor9, // background of panel
titleBar: lightColor9, // ?
padding: widget.Insets{
Left: 30,
Right: 30,
Top: 20,
Bottom: 20,
},
}, nil
}
func newTabBookResources(fonts *fonts) (*tabBookResources, error) {
return &tabBookResources{
buttonFace: fonts.face,
buttonText: &widget.ButtonTextColor{
Idle: lightColor, // tab button text
Disabled: darkColor, // disabled tab button text
},
buttonPadding: widget.Insets{
Left: 30,
Right: 30,
},
}, nil
}
func newHeaderResources(fonts *fonts) (*headerResources, error) {
return &headerResources{
background: lightColor9,
padding: widget.Insets{
Left: 25,
Right: 25,
Top: 4,
Bottom: 4,
},
face: fonts.bigTitleFace,
color: primaryColor,
}, nil
}
func newTextInputResources(fonts *fonts) (*textInputResources, error) {
return &textInputResources{
image: &widget.TextInputImage{
Idle: lightColor9, // input box background
Disabled: lightOffsetColor9, // disabled input box background
},
padding: widget.Insets{
Left: 8,
Right: 8,
Top: 4,
Bottom: 4,
},
face: fonts.face,
color: &widget.TextInputColor{
Idle: primaryColor, // input box text input color
Disabled: secondaryColor, // disabled input box text input color
Caret: primaryLightColor, // input box cursor color
DisabledCaret: secondarySelectedColor, // disabled input box cursor color
},
}, nil
}
func newTextAreaResources(fonts *fonts) (*textAreaResources, error) {
return &textAreaResources{
image: &widget.ScrollContainerImage{
Idle: primaryColor9,
Disabled: secondaryColor9,
Mask: primaryHoverColor9,
},
track: &widget.SliderTrackImage{
Idle: primaryColor9,
Hover: primaryHoverColor9,
Disabled: secondaryColor9,
},
trackPadding: widget.Insets{
Top: 5,
Bottom: 24,
},
handle: &widget.ButtonImage{
Idle: lightColor9,
Hover: secondaryHoverColor9,
Pressed: secondarySelectedColor9,
Disabled: primarySelectedColor9,
},
handleSize: 5,
face: fonts.face,
entryPadding: widget.Insets{
Left: 30,
Right: 30,
Top: 2,
Bottom: 2,
},
}, nil
}
func newToolTipResources(fonts *fonts) (*toolTipResources, error) {
return &toolTipResources{
background: lightColor9,
padding: widget.Insets{
Left: 15,
Right: 15,
Top: 10,
Bottom: 10,
},
face: fonts.toolTipFace,
color: primaryColor,
}, nil
}
func (u *uiResources) close() {
u.fonts.close()
}
func hexToColor(h string) color.Color {
u, err := strconv.ParseUint(h, 16, 0)
if err != nil {
panic(err)
}
return color.NRGBA{
R: uint8(u & 0xff0000 >> 16),
G: uint8(u & 0xff00 >> 8),
B: uint8(u & 0xff),
A: 255,
}
}