From bcffeac4c5086eba59448d4fe5d79bb786b05de2 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Fri, 6 Jun 2025 16:42:46 -0500 Subject: refactor client activities Make the activity stack explicit and move reusable activities to the activity package. --- go/activities/activity.go | 41 +++++++++ go/activities/draft.go | 212 ++++++++++++++++++++++++++++++++++++++++++++++ go/activities/sealed.go | 138 ++++++++++++++++++++++++++++++ go/client/draft.go | 199 ------------------------------------------- go/client/main.go | 17 +--- go/client/sealed.go | 138 ------------------------------ go/client/startMenu.go | 40 ++++++--- go/ui/openUrl.go | 25 ++++++ 8 files changed, 448 insertions(+), 362 deletions(-) create mode 100644 go/activities/activity.go create mode 100644 go/activities/draft.go create mode 100644 go/activities/sealed.go delete mode 100644 go/client/draft.go delete mode 100644 go/client/sealed.go create mode 100644 go/ui/openUrl.go diff --git a/go/activities/activity.go b/go/activities/activity.go new file mode 100644 index 00000000..c082b8c6 --- /dev/null +++ b/go/activities/activity.go @@ -0,0 +1,41 @@ +package activities + +import ( + "github.com/hajimehoshi/ebiten/v2" +) + +type ActivityStack struct { + activityStack []ebiten.Game +} + +var Activities ActivityStack + +type Activity = ebiten.Game + +func (s *ActivityStack) PushActivity(a Activity) { + s.activityStack = append(s.activityStack, a) +} + +func (s *ActivityStack) PopActivity() Activity { + n := len(s.activityStack) + a := s.activityStack[n-1] + s.activityStack = s.activityStack[:n-1] + return a +} + +func (s *ActivityStack) Last() Activity { + n := len(s.activityStack) + return s.activityStack[n-1] +} + +func PushActivity(a Activity) { + Activities.PushActivity(a) +} + +func PopActivity() Activity { + return Activities.PopActivity() +} + +func CurActivity() Activity { + return Activities.Last() +} diff --git a/go/activities/draft.go b/go/activities/draft.go new file mode 100644 index 00000000..10ce9671 --- /dev/null +++ b/go/activities/draft.go @@ -0,0 +1,212 @@ +package activities + +import ( + "log" + + "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/inpututil" + + "muhq.space/muhqs-game/go/game" + "muhq.space/muhqs-game/go/ui" +) + +const ( + DRAFT_BUTTON_WIDTH = 150 + DRAFT_BUTTON_HEIGHT = 40 +) + +type Draft struct { + ui.Collection + player *game.Player + ctrl *game.ChanPlayerControl + draft *game.Draft + + setInput *ui.TextInput + descInput *ui.TextInput + deckList *ui.PocList +} + +func NewDraft(width, height int, playerName string) *Draft { + d := &Draft{ + Collection: ui.Collection{Width: width, Height: height}, + } + + d.AddWidget(ui.NewFixedTextBox( + (d.Width-DRAFT_BUTTON_WIDTH)/2-DRAFT_BUTTON_WIDTH, + (d.Height-DRAFT_BUTTON_HEIGHT)/2-3*DRAFT_BUTTON_HEIGHT, + DRAFT_BUTTON_WIDTH, + DRAFT_BUTTON_HEIGHT, + "sets:", + ).Centering(true)) + + d.setInput = ui.NewTextInput( + (d.Width-DRAFT_BUTTON_WIDTH)/2, + (d.Height-DRAFT_BUTTON_HEIGHT)/2-3*DRAFT_BUTTON_HEIGHT, + DRAFT_BUTTON_WIDTH, + DRAFT_BUTTON_HEIGHT, + "base,magic,equipments", + ) + d.AddWidget(d.setInput) + + d.AddWidget(ui.NewFixedTextBox( + (d.Width-DRAFT_BUTTON_WIDTH)/2-DRAFT_BUTTON_WIDTH, + (d.Height-DRAFT_BUTTON_HEIGHT)/2-2*DRAFT_BUTTON_HEIGHT, + DRAFT_BUTTON_WIDTH, + DRAFT_BUTTON_HEIGHT, + "draft:", + ).Centering(true)) + + d.descInput = ui.NewTextInput( + (d.Width-DRAFT_BUTTON_WIDTH)/2, + (d.Height-DRAFT_BUTTON_HEIGHT)/2-2*DRAFT_BUTTON_HEIGHT, + DRAFT_BUTTON_WIDTH, + DRAFT_BUTTON_HEIGHT, + "3x[2;8]", + ) + d.AddWidget(d.descInput) + + d.AddWidget(ui.NewRoundSimpleButton( + (d.Width-DRAFT_BUTTON_WIDTH)/2+DRAFT_BUTTON_WIDTH+20, + (d.Height-DRAFT_BUTTON_HEIGHT)/2-2*DRAFT_BUTTON_HEIGHT, + DRAFT_BUTTON_WIDTH, + "?", + func(*ui.SimpleButton) { + ui.OpenUrl("https://muhq.space/muhqs-game/build/en/rules.html#draft-notation") + })) + + d.AddWidget(ui.NewFixedTextBox( + (d.Width-DRAFT_BUTTON_WIDTH)/2-DRAFT_BUTTON_WIDTH, + (d.Height-DRAFT_BUTTON_HEIGHT)/2-DRAFT_BUTTON_HEIGHT, + DRAFT_BUTTON_WIDTH, + DRAFT_BUTTON_HEIGHT, + "AI:", + ).Centering(true)) + + aiNInput := ui.NewNumberChoice( + (d.Width-DRAFT_BUTTON_WIDTH)/2, + (d.Height-DRAFT_BUTTON_HEIGHT)/2-DRAFT_BUTTON_HEIGHT, + 1, + nil, + ) + d.AddWidget(aiNInput) + + d.AddWidget(ui.NewSimpleButton( + (d.Width-DRAFT_BUTTON_WIDTH)/2, + (d.Height-DRAFT_BUTTON_HEIGHT)/2, + DRAFT_BUTTON_WIDTH, + DRAFT_BUTTON_HEIGHT, + "Start", + func(*ui.SimpleButton) { + d.startDraft(d.descInput.TextOrLabel(), d.setInput.TextOrLabel(), aiNInput.GetChoosen()) + })) + + d.player = game.NewDraftPlayer(playerName) + d.ctrl = game.NewChanPlayerControl(d.player) + d.player.Ctrl = d.ctrl + + return d +} + +func (d *Draft) Update() error { + if n := d.ctrl.RecvNotification(); n != nil { + log.Println("Received draft pick: %v\n", n) + d.presentPack(n) + } + + if err := ui.TouchManager.Update(); err != nil { + return err + } + + if err := d.Collection.Update(); err != nil { + return err + } + + if inpututil.IsKeyJustPressed(ebiten.KeyEscape) { + PopActivity() + } + + return nil +} + +func (d *Draft) presentPack(n *game.PlayerNotification) { + pack := n.Context.(game.PileOfCards) + grid := ui.NewCardGrid(0, 0, d.Width-SEALED_DECK_STRIP_WIDTH, d.Height, 0.5, pack).Columns(3) + selectCard := func(x, y int) { + _card := grid.FindObjectAt(x, y) + if _card == nil { + return + } + + card := _card.(*game.Card) + d.RemoveWidget(grid) + d.ctrl.SendAction(game.NewDraftPick(d.player, pack, card)) + } + grid.RegisterHandler("click", selectCard) + d.AddWidget(grid) +} + +func (d *Draft) Layout(width, height int) (int, int) { + return d.Width, d.Height +} + +func (d *Draft) startDraft(desc string, setList string, aiN int) { + + log.Printf("starting %s draft from '%s'\n", desc, setList) + + var sets []game.SetIdentifier + var err error + if sets, err = game.SetListToSets(setList); err != nil { + d.setInput.Bg(ui.WarningBg) + d.setInput.SetInput("") + return + } + + d.draft = game.NewDraft([]*game.Player{d.player}, desc, sets) + + log.Println(aiN) + for _ = range aiN { + log.Println("add ai") + d.draft.AddRandomAi() + } + + if !d.draft.Valid() { + d.descInput.Bg(ui.WarningBg) + d.descInput.SetInput("") + return + } + d.Clear() + + d.deckList = ui.NewPocList(d.Width-SEALED_DECK_STRIP_WIDTH/2, d.Height-DRAFT_BUTTON_HEIGHT-20, d.player.Deck) + d.deckList.Bg(ui.Gray) + { + cardsInDeck := 0 + d.deckList.RegisterHandler("update", func() error { + if n := d.player.Deck.Size(); n > cardsInDeck { + d.deckList.ForceRedraw() + cardsInDeck = n + } + return nil + }) + } + d.AddWidget(d.deckList) + + d.AddWidget(ui.NewSimpleButton( + d.Width-SEALED_DECK_STRIP_WIDTH/2-DRAFT_BUTTON_WIDTH/2, + d.Height-DRAFT_BUTTON_HEIGHT, + DRAFT_BUTTON_WIDTH, + DRAFT_BUTTON_HEIGHT, + "Done", + func(*ui.SimpleButton) { + d.done() + })) + + go d.draft.Run() +} + +func (d *Draft) done() { + PopActivity() +} + +func (d *Draft) GetDeckList() string { + return d.player.Deck.ToList() +} diff --git a/go/activities/sealed.go b/go/activities/sealed.go new file mode 100644 index 00000000..7438e89d --- /dev/null +++ b/go/activities/sealed.go @@ -0,0 +1,138 @@ +package activities + +import ( + "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/inpututil" + + "muhq.space/muhqs-game/go/game" + "muhq.space/muhqs-game/go/ui" +) + +const ( + SEALED_DECK_STRIP_WIDTH = 200 + SEALED_BUTTON_WIDTH = 150 + SEALED_BUTTON_HEIGHT = 40 +) + +type Sealed struct { + ui.Collection + + setInput *ui.TextInput + + pool game.PileOfCards + Deck game.PileOfCards +} + +func NewSealed(width, height int) *Sealed { + s := &Sealed{ + Collection: ui.Collection{Width: width, Height: height}, + } + + s.AddWidget(ui.NewFixedTextBox( + (s.Width-SEALED_BUTTON_WIDTH)/2-SEALED_BUTTON_WIDTH, + (s.Height-SEALED_BUTTON_HEIGHT)/2-SEALED_BUTTON_HEIGHT, + SEALED_BUTTON_WIDTH, + SEALED_BUTTON_HEIGHT, + "sets:", + ).Centering(true)) + + s.setInput = ui.NewTextInput( + (s.Width-SEALED_BUTTON_WIDTH)/2, + (s.Height-SEALED_BUTTON_HEIGHT)/2-SEALED_BUTTON_HEIGHT, + SEALED_BUTTON_WIDTH, + SEALED_BUTTON_HEIGHT, + "base,equipments,magic", + ) + s.AddWidget(s.setInput) + + s.AddWidget(ui.NewSimpleButton( + (s.Width-SEALED_BUTTON_WIDTH)/2, + (s.Height-SEALED_BUTTON_HEIGHT)/2, + SEALED_BUTTON_WIDTH, + SEALED_BUTTON_HEIGHT, + "Start", + func(*ui.SimpleButton) { + s.startSealed(s.setInput.TextOrLabel()) + })) + + return s +} + +func (s *Sealed) Update() error { + if err := ui.TouchManager.Update(); err != nil { + return err + } + + if err := s.Collection.Update(); err != nil { + return err + } + + if inpututil.IsKeyJustPressed(ebiten.KeyEscape) { + Activities.PopActivity() + } + + return nil +} + +func (s *Sealed) Layout(width, height int) (int, int) { + return s.Width, s.Height +} + +func (s *Sealed) startSealed(setList string) { + sets, err := game.SetListToSets(setList) + if err != nil { + s.setInput.Bg(ui.WarningBg) + s.setInput.SetInput("") + return + } + + s.pool = game.NewPileOfCards() + s.Deck = game.NewPileOfCards() + + s.Clear() + + for _, set := range sets { + setDeck := game.NewDeck() + for _, c := range game.NewDeckFromCardPaths(set.CardPaths()).Cards() { + if c.IsBuyable() { + setDeck.AddCard(c) + } + } + setDeck.MoveInto(s.pool) + } + + deckList := ui.NewPocList(s.Width-SEALED_DECK_STRIP_WIDTH/2, s.Height-SEALED_BUTTON_HEIGHT-20, s.Deck) + deckList.Bg(ui.Gray) + s.AddWidget(deckList) + + grid := ui.NewCardGrid(0, 0, s.Width-SEALED_DECK_STRIP_WIDTH, s.Height, 0.5, s.pool).Columns(3) + selectCard := func(x, y int) { + _card := grid.FindObjectAt(x, y) + if _card == nil { + return + } + + card := _card.(*game.Card) + s.pool.MoveCard(card, s.Deck) + grid.ForceRedraw() + deckList.ForceRedraw() + } + grid.RegisterHandler("click", selectCard) + s.AddWidget(grid) + + s.AddWidget(ui.NewSimpleButton( + s.Width-SEALED_DECK_STRIP_WIDTH/2-SEALED_BUTTON_WIDTH/2, + s.Height-SEALED_BUTTON_HEIGHT, + SEALED_BUTTON_WIDTH, + SEALED_BUTTON_HEIGHT, + "Done", + func(*ui.SimpleButton) { + s.done() + })) +} + +func (s *Sealed) done() { + Activities.PopActivity() + // startMenu := CurActivity().(*StartMenu) + // startMenu.deckInput.SetInput(s.deck.ToList()) +} diff --git a/go/client/draft.go b/go/client/draft.go deleted file mode 100644 index 3950094f..00000000 --- a/go/client/draft.go +++ /dev/null @@ -1,199 +0,0 @@ -package main - -import ( - "log" - - "github.com/hajimehoshi/ebiten/v2" - "github.com/hajimehoshi/ebiten/v2/inpututil" - - "muhq.space/muhqs-game/go/game" - "muhq.space/muhqs-game/go/ui" -) - -type Draft struct { - ui.Collection - app *app - player *game.Player - ctrl *game.ChanPlayerControl - draft *game.Draft - - setInput *ui.TextInput - descInput *ui.TextInput - deckList *ui.PocList -} - -func NewDraft(width, height int, app *app) *Draft { - d := &Draft{ - app: app, - Collection: ui.Collection{Width: width, Height: height}, - } - - d.AddWidget(ui.NewFixedTextBox( - (d.Width-START_BUTTON_WIDTH)/2-START_BUTTON_WIDTH, - (d.Height-START_BUTTON_HEIGHT)/2-3*START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "sets:", - ).Centering(true)) - - d.setInput = ui.NewTextInput( - (d.Width-START_BUTTON_WIDTH)/2, - (d.Height-START_BUTTON_HEIGHT)/2-3*START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "base,magic,equipments", - ) - d.AddWidget(d.setInput) - - d.AddWidget(ui.NewFixedTextBox( - (d.Width-START_BUTTON_WIDTH)/2-START_BUTTON_WIDTH, - (d.Height-START_BUTTON_HEIGHT)/2-2*START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "draft:", - ).Centering(true)) - - d.descInput = ui.NewTextInput( - (d.Width-START_BUTTON_WIDTH)/2, - (d.Height-START_BUTTON_HEIGHT)/2-2*START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "3x[2;8]", - ) - d.AddWidget(d.descInput) - - d.AddWidget(ui.NewFixedTextBox( - (d.Width-START_BUTTON_WIDTH)/2-START_BUTTON_WIDTH, - (d.Height-START_BUTTON_HEIGHT)/2-START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "AI:", - ).Centering(true)) - - aiNInput := ui.NewNumberChoice( - (d.Width-START_BUTTON_WIDTH)/2, - (d.Height-START_BUTTON_HEIGHT)/2-START_BUTTON_HEIGHT, - 1, - nil, - ) - d.AddWidget(aiNInput) - - d.AddWidget(ui.NewSimpleButton( - (d.Width-START_BUTTON_WIDTH)/2, - (d.Height-START_BUTTON_HEIGHT)/2, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "Start", - func(*ui.SimpleButton) { - d.startDraft(d.descInput.TextOrLabel(), d.setInput.TextOrLabel(), aiNInput.GetChoosen()) - })) - - startMenu := d.app.activities[len(d.app.activities)-1].(*StartMenu) - d.player = game.NewDraftPlayer(startMenu.playerName) - d.ctrl = game.NewChanPlayerControl(d.player) - d.player.Ctrl = d.ctrl - - return d -} - -func (d *Draft) Update() error { - if n := d.ctrl.RecvNotification(); n != nil { - log.Println("Received draft pick: %v\n", n) - d.presentPack(n) - } - - if err := ui.TouchManager.Update(); err != nil { - return err - } - - if err := d.Collection.Update(); err != nil { - return err - } - - if inpututil.IsKeyJustPressed(ebiten.KeyEscape) { - d.app.popActivity() - } - - return nil -} - -func (d *Draft) presentPack(n *game.PlayerNotification) { - pack := n.Context.(game.PileOfCards) - grid := ui.NewCardGrid(0, 0, d.Width-SEALED_DECK_STRIP_WIDTH, d.Height, 0.5, pack).Columns(3) - selectCard := func(x, y int) { - _card := grid.FindObjectAt(x, y) - if _card == nil { - return - } - - card := _card.(*game.Card) - d.RemoveWidget(grid) - d.ctrl.SendAction(game.NewDraftPick(d.player, pack, card)) - } - grid.RegisterHandler("click", selectCard) - d.AddWidget(grid) -} - -func (d *Draft) Layout(width, height int) (int, int) { - return d.Width, d.Height -} - -func (d *Draft) startDraft(desc string, setList string, aiN int) { - - log.Printf("starting %s draft from '%s'\n", desc, setList) - - var sets []game.SetIdentifier - var err error - if sets, err = game.SetListToSets(setList); err != nil { - d.setInput.Bg(ui.WarningBg) - d.setInput.SetInput("") - return - } - - d.draft = game.NewDraft([]*game.Player{d.player}, desc, sets) - - log.Println(aiN) - for _ = range aiN { - log.Println("add ai") - d.draft.AddRandomAi() - } - - if !d.draft.Valid() { - d.descInput.Bg(ui.WarningBg) - d.descInput.SetInput("") - return - } - d.Clear() - - d.deckList = ui.NewPocList(d.Width-SEALED_DECK_STRIP_WIDTH/2, d.Height-START_BUTTON_HEIGHT-20, d.player.Deck) - d.deckList.Bg(ui.Gray) - { - cardsInDeck := 0 - d.deckList.RegisterHandler("update", func() error { - if n := d.player.Deck.Size(); n > cardsInDeck { - d.deckList.ForceRedraw() - cardsInDeck = n - } - return nil - }) - } - d.AddWidget(d.deckList) - - d.AddWidget(ui.NewSimpleButton( - d.Width-SEALED_DECK_STRIP_WIDTH/2-START_BUTTON_WIDTH/2, - d.Height-START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "Done", - func(*ui.SimpleButton) { - d.done() - })) - - go d.draft.Run() -} - -func (d *Draft) done() { - startMenu := d.app.activities[len(d.app.activities)-2].(*StartMenu) - startMenu.deckInput.SetInput(d.player.Deck.ToList()) - d.app.popActivity() -} diff --git a/go/client/main.go b/go/client/main.go index 4d46ed9a..b631269e 100644 --- a/go/client/main.go +++ b/go/client/main.go @@ -8,6 +8,7 @@ import ( "github.com/hajimehoshi/ebiten/v2" + "muhq.space/muhqs-game/go/activities" "muhq.space/muhqs-game/go/font" ) @@ -21,24 +22,14 @@ var startDeckPath string type app struct { windowWidth int windowHeight int - - activities []ebiten.Game -} - -func (a *app) pushActivity(activity ebiten.Game) { - a.activities = append(a.activities, activity) -} - -func (a *app) popActivity() { - a.activities = a.activities[:len(a.activities)-1] } func (a *app) Update() error { - return a.activities[len(a.activities)-1].Update() + return activities.CurActivity().Update() } func (a *app) Draw(screen *ebiten.Image) { - a.activities[len(a.activities)-1].Draw(screen) + activities.CurActivity().Draw(screen) } func (a *app) Layout(outsideWidth, outsideHeight int) (int, int) { @@ -86,7 +77,7 @@ func main() { 1 nautics/galley` } - app.pushActivity(startMenu) + activities.PushActivity(startMenu) if err := ebiten.RunGame(app); err != nil { if err != ebiten.Termination { log.Fatal(err) diff --git a/go/client/sealed.go b/go/client/sealed.go deleted file mode 100644 index efe1006e..00000000 --- a/go/client/sealed.go +++ /dev/null @@ -1,138 +0,0 @@ -package main - -import ( - "github.com/hajimehoshi/ebiten/v2" - "github.com/hajimehoshi/ebiten/v2/inpututil" - - "muhq.space/muhqs-game/go/game" - "muhq.space/muhqs-game/go/ui" -) - -const ( - SEALED_DECK_STRIP_WIDTH = 200 -) - -type sealed struct { - ui.Collection - app *app - - setInput *ui.TextInput - - pool game.PileOfCards - deck game.PileOfCards -} - -func NewSealed(width, height int, app *app) *sealed { - s := &sealed{ - app: app, - Collection: ui.Collection{Width: width, Height: height}, - } - - s.AddWidget(ui.NewFixedTextBox( - (s.Width-START_BUTTON_WIDTH)/2-START_BUTTON_WIDTH, - (s.Height-START_BUTTON_HEIGHT)/2-START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "sets:", - ).Centering(true)) - - s.setInput = ui.NewTextInput( - (s.Width-START_BUTTON_WIDTH)/2, - (s.Height-START_BUTTON_HEIGHT)/2-START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "base,equipments,magic", - ) - s.AddWidget(s.setInput) - - s.AddWidget(ui.NewSimpleButton( - (s.Width-START_BUTTON_WIDTH)/2, - (s.Height-START_BUTTON_HEIGHT)/2, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "Start", - func(*ui.SimpleButton) { - s.startSealed(s.setInput.TextOrLabel()) - })) - - return s -} - -func (s *sealed) Update() error { - if err := ui.TouchManager.Update(); err != nil { - return err - } - - if err := s.Collection.Update(); err != nil { - return err - } - - if inpututil.IsKeyJustPressed(ebiten.KeyEscape) { - s.app.popActivity() - } - - return nil -} - -func (s *sealed) Layout(width, height int) (int, int) { - return s.Width, s.Height -} - -func (s *sealed) startSealed(setList string) { - sets, err := game.SetListToSets(setList) - if err != nil { - s.setInput.Bg(ui.WarningBg) - s.setInput.SetInput("") - return - } - - s.pool = game.NewPileOfCards() - s.deck = game.NewPileOfCards() - - s.Clear() - - for _, set := range sets { - setDeck := game.NewDeck() - for _, c := range game.NewDeckFromCardPaths(set.CardPaths()).Cards() { - if c.IsBuyable() { - setDeck.AddCard(c) - } - } - setDeck.MoveInto(s.pool) - } - - deckList := ui.NewPocList(s.Width-SEALED_DECK_STRIP_WIDTH/2, s.Height-START_BUTTON_HEIGHT-20, s.deck) - deckList.Bg(ui.Gray) - s.AddWidget(deckList) - - grid := ui.NewCardGrid(0, 0, s.Width-SEALED_DECK_STRIP_WIDTH, s.Height, 0.5, s.pool).Columns(3) - selectCard := func(x, y int) { - _card := grid.FindObjectAt(x, y) - if _card == nil { - return - } - - card := _card.(*game.Card) - s.pool.MoveCard(card, s.deck) - grid.ForceRedraw() - deckList.ForceRedraw() - } - grid.RegisterHandler("click", selectCard) - s.AddWidget(grid) - - s.AddWidget(ui.NewSimpleButton( - s.Width-SEALED_DECK_STRIP_WIDTH/2-START_BUTTON_WIDTH/2, - s.Height-START_BUTTON_HEIGHT, - START_BUTTON_WIDTH, - START_BUTTON_HEIGHT, - "Done", - func(*ui.SimpleButton) { - s.done() - })) -} - -func (s *sealed) done() { - startMenu := s.app.activities[len(s.app.activities)-2].(*StartMenu) - startMenu.deckInput.SetInput(s.deck.ToList()) - s.app.popActivity() -} diff --git a/go/client/startMenu.go b/go/client/startMenu.go index 10fa8e1f..10b9e23d 100644 --- a/go/client/startMenu.go +++ b/go/client/startMenu.go @@ -3,6 +3,7 @@ package main import ( "log" + "muhq.space/muhqs-game/go/activities" "muhq.space/muhqs-game/go/game" "muhq.space/muhqs-game/go/ui" ) @@ -15,25 +16,28 @@ const ( DECK_LIST_HEIGHT = 500 ) -type StartMenu struct { +type startMenu struct { ui.Collection app *app deckInput *ui.TextInput + draft *activities.Draft + sealed *activities.Sealed + playerName string startDeck string remote string mapPath string } -func NewStartMenu(app *app) *StartMenu { - m := &StartMenu{app: app} +func NewStartMenu(app *app) *startMenu { + m := &startMenu{app: app} return m } -func (m *StartMenu) build() { +func (m *startMenu) build() { deckInput := ui.NewTextInput( (m.Width-DECK_LIST_WIDTH)/2, (m.Height-DECK_LIST_HEIGHT)/2, @@ -101,8 +105,8 @@ func (m *StartMenu) build() { START_BUTTON_HEIGHT, "Sealed", func(*ui.SimpleButton) { - sealed := NewSealed(m.Width, m.Height, m.app) - m.app.pushActivity(sealed) + sealed := activities.NewSealed(m.Width, m.Height) + activities.PushActivity(sealed) })) m.AddWidget(ui.NewSimpleButton( @@ -112,8 +116,8 @@ func (m *StartMenu) build() { START_BUTTON_HEIGHT, "Draft", func(*ui.SimpleButton) { - draft := NewDraft(m.Width, m.Height, m.app) - m.app.pushActivity(draft) + m.draft = activities.NewDraft(m.Width, m.Height, playerInput.Text()) + activities.PushActivity(m.draft) })) m.AddWidget(ui.NewSimpleButton( @@ -130,11 +134,23 @@ func (m *StartMenu) build() { })) } -func (m *StartMenu) Update() error { +func (m *startMenu) Update() error { if m.Widgets() == nil { m.build() } + // Get the drafted deck + if m.draft != nil { + m.deckInput.SetInput(m.draft.GetDeckList()) + m.draft = nil + } + + // Get the sealed deck + if m.sealed != nil { + m.deckInput.SetInput(m.sealed.Deck.ToList()) + m.sealed = nil + } + if err := ui.TouchManager.Update(); err != nil { return err } @@ -142,11 +158,11 @@ func (m *StartMenu) Update() error { return m.Collection.Update() } -func (m *StartMenu) Layout(width, height int) (int, int) { +func (m *startMenu) Layout(width, height int) (int, int) { return m.Width, m.Height } -func (m *StartMenu) startGame() { +func (m *startMenu) startGame() { var state game.State if m.remote != "" { log.Fatal("Remote games are currently not implemented") @@ -162,5 +178,5 @@ func (m *StartMenu) startGame() { g.gameState.AddNewAiPlayer("kraken", color) } - m.app.pushActivity(g.Start()) + activities.PushActivity(g.Start()) } diff --git a/go/ui/openUrl.go b/go/ui/openUrl.go new file mode 100644 index 00000000..7e227ba8 --- /dev/null +++ b/go/ui/openUrl.go @@ -0,0 +1,25 @@ +package ui + +import ( + "os/exec" + "runtime" +) + +// https://stackoverflow.com/questions/39320371/how-start-web-server-to-open-page-in-browser-in-golang +// open opens the specified URL in the default browser of the user. +func OpenUrl(url string) error { + var cmd string + var args []string + + switch runtime.GOOS { + case "windows": + cmd = "cmd" + args = []string{"/c", "start"} + case "darwin": + cmd = "open" + default: // "linux", "freebsd", "openbsd", "netbsd" + cmd = "xdg-open" + } + args = append(args, url) + return exec.Command(cmd, args...).Start() +} -- cgit v1.2.3