feat(frontend): login interface boilerplate

This commit is contained in:
Muhammad Nauman Raza 2023-07-31 13:57:50 +01:00
parent dba75dde1b
commit 29aa823a0f
2 changed files with 187 additions and 26 deletions

142
frontend/ui/login.go Normal file
View file

@ -0,0 +1,142 @@
package ui
import (
// Misc.
"fmt"
// Image
img "image"
// Ambition
// p "github.com/devraza/ambition/frontend/player"
// EbitenUI
"github.com/ebitenui/ebitenui/image"
"github.com/ebitenui/ebitenui/widget"
)
func makeLoginWindow(width, height int, root *widget.Container, shown *widget.Container) {
// Define the contents of the login window
loginContainer := widget.NewContainer(
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["gray"])),
// the container will use a row layout to layout the textinput widgets
widget.ContainerOpts.Layout(widget.NewRowLayout(
widget.RowLayoutOpts.Direction(widget.DirectionVertical),
widget.RowLayoutOpts.Spacing(10),
widget.RowLayoutOpts.Padding(widget.NewInsetsSimple(20)))),
)
loginContainer.AddChild(widget.NewText(
widget.TextOpts.Text("Login", headingFace, ui.colors["purple"]),
widget.TextOpts.WidgetOpts(widget.WidgetOpts.LayoutData(widget.RowLayoutData{
Position: widget.RowLayoutPositionCenter,
Stretch: false,
})),
))
loginContainer.AddChild(widget.NewGraphic(
widget.GraphicOpts.WidgetOpts(widget.WidgetOpts.LayoutData(widget.RowLayoutData{
Stretch: true,
MaxHeight: 2,
})),
widget.GraphicOpts.ImageNineSlice(image.NewNineSliceColor(ui.colors["gray"])),
))
// Create the text inputs
usernameInput := widget.NewTextInput(
widget.TextInputOpts.WidgetOpts(
widget.WidgetOpts.LayoutData(widget.RowLayoutData{
Position: widget.RowLayoutPositionCenter,
Stretch: true,
}),
),
widget.TextInputOpts.Image(&widget.TextInputImage{
Idle: image.NewNineSliceColor(ui.colors["black"]),
Disabled: image.NewNineSliceColor(ui.colors["cyan"]),
}),
widget.TextInputOpts.Face(defaultFace),
widget.TextInputOpts.Color(&widget.TextInputColor{
Idle: ui.colors["white"],
Disabled: ui.colors["light_gray"],
Caret: ui.colors["green"],
}),
widget.TextInputOpts.Padding(widget.NewInsetsSimple(10)),
widget.TextInputOpts.CaretOpts(
widget.CaretOpts.Size(defaultFace, 2),
),
widget.TextInputOpts.Placeholder("Username"),
widget.TextInputOpts.SubmitHandler(func(args *widget.TextInputChangedEventArgs) {
fmt.Println("Text Submitted: ", args.InputText)
}),
)
passwordInput := widget.NewTextInput(
widget.TextInputOpts.WidgetOpts(
widget.WidgetOpts.LayoutData(widget.RowLayoutData{
Position: widget.RowLayoutPositionCenter,
Stretch: true,
}),
),
widget.TextInputOpts.Image(&widget.TextInputImage{
Idle: image.NewNineSliceColor(ui.colors["black"]),
Disabled: image.NewNineSliceColor(ui.colors["cyan"]),
}),
widget.TextInputOpts.Face(defaultFace),
widget.TextInputOpts.Color(&widget.TextInputColor{
Idle: ui.colors["white"],
Disabled: ui.colors["light_gray"],
Caret: ui.colors["green"],
}),
widget.TextInputOpts.Padding(widget.NewInsetsSimple(10)),
widget.TextInputOpts.CaretOpts(
widget.CaretOpts.Size(defaultFace, 2),
),
// Hide the text inputted
widget.TextInputOpts.Secure(true),
widget.TextInputOpts.Placeholder("Password"),
widget.TextInputOpts.SubmitHandler(func(args *widget.TextInputChangedEventArgs) {
fmt.Println("Text Submitted: ", args.InputText)
}),
)
// Add the text inputs to the login window
loginContainer.AddChild(usernameInput)
loginContainer.AddChild(passwordInput)
loginContainer.AddChild(widget.NewGraphic(
widget.GraphicOpts.WidgetOpts(widget.WidgetOpts.LayoutData(widget.RowLayoutData{
Stretch: true,
MaxHeight: 20,
})),
widget.GraphicOpts.ImageNineSlice(image.NewNineSliceColor(ui.colors["gray"])),
))
// Define the 'confirm' button
confirmButton := widget.NewButton(
// Button options
widget.ButtonOpts.WidgetOpts(
// Center the button both horizontally and vertically
widget.WidgetOpts.LayoutData(widget.RowLayoutData{
Position: widget.RowLayoutPositionCenter,
Stretch: false,
}),
),
// More options
widget.ButtonOpts.Image(buttonImage),
widget.ButtonOpts.Text("Confirm", defaultFace, &widget.ButtonTextColor{
Idle: ui.colors["white"],
}),
// Define the padding on the button
widget.ButtonOpts.TextPadding(widget.Insets{
Left: 20,
Right: 20,
Top: 10,
Bottom: 10,
}),
// Button on-click handler
widget.ButtonOpts.ClickedHandler(func(args *widget.ButtonClickedEventArgs) {
removeContainer(root, loginContainer)
addContainer(root, shown)
}),
)
loginContainer.AddChild(confirmButton)
// Place and show the login container
placeContainer(loginContainer, ui.width/3, ui.height/4, img.Point{ui.width / 3, ui.height / 3})
addContainer(root, loginContainer)
}

View file

@ -5,9 +5,6 @@ import (
img "image" img "image"
"image/color" "image/color"
// Misc.
// "fmt"
// Ambition // Ambition
p "github.com/devraza/ambition/frontend/player" p "github.com/devraza/ambition/frontend/player"
@ -27,6 +24,7 @@ type UI struct {
Base ebitenui.UI Base ebitenui.UI
colors map[string]color.RGBA colors map[string]color.RGBA
width, height int width, height int
textInput *widget.TextInput
} }
// Get the player from the `player` package // Get the player from the `player` package
@ -35,7 +33,7 @@ var player = p.GetPlayer()
// The `hazakura` colorscheme (default) // The `hazakura` colorscheme (default)
var hazakura = map[string]color.RGBA{ var hazakura = map[string]color.RGBA{
// The monotone colors // The monotone colors
"dark_black": color.RGBA{0x0f, 0x0f, 0x0d, 0xff}, "dark_black": color.RGBA{0x0d, 0x0d, 0x0f, 0xff},
"black": color.RGBA{0x15, 0x15, 0x17, 0xff}, "black": color.RGBA{0x15, 0x15, 0x17, 0xff},
"dark_gray": color.RGBA{0x24, 0x24, 0x26, 0xff}, "dark_gray": color.RGBA{0x24, 0x24, 0x26, 0xff},
"gray": color.RGBA{0x27, 0x27, 0x2b, 0xff}, "gray": color.RGBA{0x27, 0x27, 0x2b, 0xff},
@ -54,16 +52,20 @@ var hazakura = map[string]color.RGBA{
"yellow": color.RGBA{0xd9, 0xd5, 0x64, 0xff}, "yellow": color.RGBA{0xd9, 0xd5, 0x64, 0xff},
} }
var ui UI
// Make the different faces
var headingFace, _ = makeFace(18, fonts.FiraBold_ttf)
var defaultFace, _ = makeFace(14, fonts.FiraRegular_ttf)
// Load the images for the button states
var buttonImage, _ = loadButtonImage()
// Function for UI initialization // Function for UI initialization
func UiInit(width, height int) UI { func UiInit(width, height int) UI {
var ui UI
// Define the UI colors // Define the UI colors
ui.colors = hazakura ui.colors = hazakura
// Load the images for the button states
buttonImage, _ := loadButtonImage()
// Get the window width/height // Get the window width/height
ui.width = width ui.width = width
ui.height = height ui.height = height
@ -74,10 +76,6 @@ func UiInit(width, height int) UI {
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["dark_black"])), widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["dark_black"])),
) )
// Make the different faces
headingFace, _ := makeFace(18, fonts.FiraBold_ttf)
defaultFace, _ := makeFace(14, fonts.FiraRegular_ttf)
// Create the 'Profile' tab // Create the 'Profile' tab
tabProfile := widget.NewTabBookTab("Profile", tabProfile := widget.NewTabBookTab("Profile",
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["gray"])), widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["gray"])),
@ -156,34 +154,56 @@ func UiInit(width, height int) UI {
// Define the contents of the chat window // Define the contents of the chat window
chatContainer := widget.NewContainer( chatContainer := widget.NewContainer(
widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["black"])), widget.ContainerOpts.BackgroundImage(image.NewNineSliceColor(ui.colors["black"])),
widget.ContainerOpts.Layout(widget.NewAnchorLayout()), widget.ContainerOpts.Layout(widget.NewAnchorLayout(
widget.AnchorLayoutOpts.Padding(widget.NewInsetsSimple(20)),
)),
) )
chatContainer.AddChild(widget.NewText( chatContainer.AddChild(widget.NewText(
widget.TextOpts.Text("Placeholder", defaultFace, ui.colors["white"]), widget.TextOpts.Text("Chat", headingFace, ui.colors["blue"]),
widget.TextOpts.WidgetOpts(widget.WidgetOpts.LayoutData(widget.AnchorLayoutData{ widget.TextOpts.WidgetOpts(widget.WidgetOpts.LayoutData(widget.AnchorLayoutData{
HorizontalPosition: widget.AnchorLayoutPositionCenter, HorizontalPosition: widget.AnchorLayoutPositionStart,
VerticalPosition: widget.AnchorLayoutPositionCenter, VerticalPosition: widget.AnchorLayoutPositionStart,
})), })),
)) ))
chatDimensionX, chatDimensionY := int(float32(width)/3.5), int(float32(height)/3) // Place and show the chat container
chat := img.Rect(0, 0, chatDimensionX, chatDimensionY) placeContainer(chatContainer, int(float32(ui.width)/3.5), int(float32(ui.height)/3.3), img.Point{0, ui.height - int(float32(ui.height)/3.3)})
chat = chat.Add(img.Point{0, height - chatDimensionY}) addContainer(leftBar, chatContainer)
// Set the position and size of the chat window
chatContainer.SetLocation(chat) // Create the login window
leftBar.AddChild(chatContainer) makeLoginWindow(ui.width, ui.height, root, leftBar)
// Set the position and size of the left bar // Set the position and size of the left bar
leftBar.SetLocation(img.Rect(0, 0, int(float32(width)/3.5), height)) leftBar.SetLocation(img.Rect(0, 0, int(float32(width)/3.5), height))
// Add the left bar to the root container // Add the left bar to the root container
root.AddChild(leftBar) //root.AddChild(leftBar)
// Set the base container to be the root container
ui.Base.Container = root ui.Base.Container = root
return ui return ui
} }
// Set the size/location of a container
func placeContainer(container *widget.Container, x int, y int, vector img.Point) {
DimensionX, DimensionY := x, y
placement := img.Rect(0, 0, DimensionX, DimensionY)
placement = placement.Add(vector)
// Set the position and size of the container
container.SetLocation(placement)
}
// Add a container to a parent container
func addContainer(parent *widget.Container, child *widget.Container) {
parent.AddChild(child)
}
// Hide a container
func removeContainer(parent *widget.Container, child *widget.Container) {
parent.RemoveChild(child)
}
// Set a window's location and open the window // Set a window's location and open the window
func showWindow(window *widget.Window, ui UI, v float32, h float32) { func showWindow(window *widget.Window, v float32, h float32) {
// Get the preferred size of the content // Get the preferred size of the content
x, y := window.Contents.PreferredSize() x, y := window.Contents.PreferredSize()
// Create a rect with the preferred size of the content // Create a rect with the preferred size of the content
@ -192,7 +212,6 @@ func showWindow(window *widget.Window, ui UI, v float32, h float32) {
r = r.Add(img.Point{int(v), int(h)}) r = r.Add(img.Point{int(v), int(h)})
// Set the windows location to the rect // Set the windows location to the rect
window.SetLocation(r) window.SetLocation(r)
} }
// Create progressbars for all the player stats // Create progressbars for all the player stats