func (kb KeyBinds) MakeKeyMap() KeyMap { key_map := make(KeyMap) for key, val := range kb { parts := strings.Split(val, ",") var binds []gin.Key for i, part := range parts { kids := getKeysFromString(part) if len(kids) == 1 { binds = append(binds, gin.In().GetKey(kids[0])) } else { // The last kid is the main kid and the rest are modifiers main := kids[len(kids)-1] kids = kids[0 : len(kids)-1] var down []bool for _ = range kids { down = append(down, true) } binds = append(binds, gin.In().BindDerivedKey(fmt.Sprintf("%s:%d", key, i), gin.In().MakeBinding(main, kids, down))) } } if len(binds) == 1 { key_map[key] = binds[0] } else { var actual_binds []gin.Binding for i := range binds { actual_binds = append(actual_binds, gin.In().MakeBinding(binds[i].Id(), nil, nil)) } key_map[key] = gin.In().BindDerivedKey("name", actual_binds...) } } return key_map }
func draggingAndZooming(dz draggerZoomer) { if ui.FocusWidget() != nil { dragging = false zooming = false sys.HideCursor(false) return } var zoom float64 if gin.In().GetKey(gin.Space).FramePressAmt() > 0 { zoom = gin.In().GetKey(gin.MouseWheelVertical).FramePressAmt() } dz.Zoom(zoom / 100) dz.Zoom(key_map["zoom in"].FramePressAmt() / 20) dz.Zoom(-key_map["zoom out"].FramePressAmt() / 20) if key_map["drag"].IsDown() != dragging { dragging = !dragging } if dragging { mx := gin.In().GetKey(gin.MouseXAxis).FramePressAmt() my := gin.In().GetKey(gin.MouseYAxis).FramePressAmt() if mx != 0 || my != 0 { dz.Drag(-mx, my) } } if (dragging || zooming) != hiding { hiding = (dragging || zooming) sys.HideCursor(hiding) } }
func (ep *EntityPlacer) Think(g *gui.Gui, t int64) { if ep.last_t == 0 { ep.last_t = t return } dt := t - ep.last_t ep.last_t = t if ep.mx == 0 && ep.my == 0 { ep.mx, ep.my = gin.In().GetCursor("Mouse").Point() } for _, button := range ep.buttons { button.Think(ep.region.X, ep.region.Y, ep.mx, ep.my, dt) } hovered := false for i, button := range ep.ent_buttons { if button.Over(ep.mx, ep.my) { hovered = true if ep.hovered == nil || ep.roster_names[i] != ep.hovered.Name { ep.hovered = MakeEntity(ep.roster_names[i], ep.game) } } } if hovered == false { ep.hovered = nil } if ep.hovered != nil { ep.hovered.Think(dt) } }
func (a *Interact) HandleInput(group gui.EventGroup, g *game.Game) (bool, game.ActionExec) { if found, event := group.FindEvent(gin.MouseLButton); found && event.Type == gin.Press { bx, by := g.GetViewer().WindowToBoard(gin.In().GetCursor("Mouse").Point()) room_num := a.ent.CurrentRoom() room := g.House.Floors[0].Rooms[room_num] for door_num, door := range room.Doors { rect := makeRectForDoor(room, door) if rect.Contains(float64(bx), float64(by)) { var exec interactExec exec.Toggle_door = true exec.SetBasicData(a.ent, a) exec.Room = room_num exec.Door = door_num return true, &exec } } } target := g.HoveredEnt() if target == nil { return false, nil } if found, event := group.FindEvent(gin.MouseLButton); found && event.Type == gin.Press { for i := range a.targets { if a.targets[i] == target && distBetweenEnts(a.ent, target) <= a.Range { var exec interactExec exec.SetBasicData(a.ent, a) exec.Target = target.Id return true, &exec } } return true, nil } return false, nil }
func (c *Console) Respond(ui *gui.Gui, group gui.EventGroup) bool { if found, event := group.FindEvent(GetDefaultKeyMap()["console"].Id()); found && event.Type == gin.Press { if group.Focus { ui.DropFocus() } else { ui.TakeFocus(c) } return true } if found, event := group.FindEvent(gin.Left); found && event.Type == gin.Press { c.xscroll += 250 } if found, event := group.FindEvent(gin.Right); found && event.Type == gin.Press { c.xscroll -= 250 } if c.xscroll > 0 { c.xscroll = 0 } if found, event := group.FindEvent(gin.Space); found && event.Type == gin.Press { c.xscroll = 0 } if group.Events[0].Type == gin.Press { r := rune(group.Events[0].Key.Id()) if r < 256 { if gin.In().GetKey(gin.EitherShift).IsDown() { r = unicode.ToUpper(r) } c.cmd = append(c.cmd, byte(r)) } } return group.Focus }
func (a *Move) Prep(ent *game.Entity, g *game.Game) bool { a.ent = ent fx, fy := g.GetViewer().WindowToBoard(gin.In().GetCursor("Mouse").Point()) a.findPath(ent, int(fx), int(fy)) a.threshold = a.ent.Stats.ApCur() return true }
func (sm *SystemMenu) Think(g *gui.Gui, t int64) { if sm.last_t == 0 { sm.last_t = t return } dt := t - sm.last_t sm.last_t = t if sm.mx == 0 && sm.my == 0 { sm.mx, sm.my = gin.In().GetCursor("Mouse").Point() } if sm.focus { for _, button := range sm.buttons { button.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt) } // This makes it so that the button lights up while the menu sm.layout.Main.Think(0, 0, sm.layout.Main.bounds.x+1, sm.layout.Main.bounds.y+1, dt) } else { sm.layout.Main.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt) } if sm.saved_time != (time.Time{}) && time.Now().Sub(sm.saved_time).Seconds() > 3 { sm.saved_alpha = doApproach(sm.saved_alpha, 0.0, dt) } sm.focus = (g.FocusWidget() == sm) }
func (hdt *houseDataTab) Think(ui *gui.Gui, t int64) { if hdt.temp_room != nil { mx, my := gin.In().GetCursor("Mouse").Point() bx, by := hdt.viewer.WindowToBoard(mx, my) cx, cy := hdt.temp_room.Pos() hdt.temp_room.X = int(bx - hdt.drag_anchor.x) hdt.temp_room.Y = int(by - hdt.drag_anchor.y) dx := hdt.temp_room.X - cx dy := hdt.temp_room.Y - cy for i := range hdt.temp_spawns { hdt.temp_spawns[i].X += dx hdt.temp_spawns[i].Y += dy } hdt.temp_room.invalid = !hdt.house.Floors[0].canAddRoom(hdt.temp_room) } hdt.VerticalTable.Think(ui, t) num_floors := hdt.num_floors.GetComboedIndex() + 1 if len(hdt.house.Floors) != num_floors { for len(hdt.house.Floors) < num_floors { hdt.house.Floors = append(hdt.house.Floors, &Floor{}) } if len(hdt.house.Floors) > num_floors { hdt.house.Floors = hdt.house.Floors[0:num_floors] } } hdt.house.Name = hdt.name.GetText() hdt.house.Icon.Path = base.Path(hdt.icon.GetPath()) }
func (sys *sysObj) Think() { sys.os.Think() events, horizon := sys.os.GetInputEvents() for i := range events { events[i].Timestamp -= sys.start_ms } sys.events = gin.In().Think(horizon-sys.start_ms, false, events) }
func (te *TextEntry) Think(x, y, mx, my int, dt int64) { if te.Entry.Default != "" { te.Entry.text = te.Entry.Default te.Entry.Default = "" } te.Button.Think(x, y, mx, my, dt) te.setCursor(gin.In().GetCursor("Mouse").Point()) }
func (rv *RoomViewer) Think(*gui.Gui, int64) { if rv.size != rv.room.Size { rv.size = rv.room.Size rv.makeMat() } mx, my := rv.WindowToBoard(gin.In().GetCursor("Mouse").Point()) rv.mx = int(mx) rv.my = int(my) }
func (a *AoeAttack) Prep(ent *game.Entity, g *game.Game) bool { if !a.Preppable(ent, g) { return false } a.ent = ent bx, by := g.GetViewer().WindowToBoard(gin.In().GetCursor("Mouse").Point()) a.tx = int(bx) a.ty = int(by) return true }
func (w *WallPanel) Think(ui *gui.Gui, t int64) { if w.wall_texture != nil { px, py := gin.In().GetCursor("Mouse").Point() tx := float32(px) - w.drag_anchor.X ty := float32(py) - w.drag_anchor.Y bx, by := w.viewer.WindowToBoardf(tx, ty) w.wall_texture.X = bx w.wall_texture.Y = by } w.VerticalTable.Think(ui, t) }
func characterFromEventGroup(event_group EventGroup) byte { for _, event := range event_group.Events { if v, ok := shift_mapping[event.Key.Id()]; ok { if gin.In().GetKey(gin.EitherShift).IsDown() { return v } else { return byte(event.Key.Id()) } } } return 0 }
func (te *TextEntry) Respond(group gui.EventGroup, data interface{}) bool { if te.Button.Respond(group, data) { return true } if !te.Entry.entering { return false } for _, event := range group.Events { if event.Type == gin.Press { id := event.Key.Id() if id <= 255 && valid_keys[byte(id)] { b := byte(id) if gin.In().GetKey(gin.EitherShift).CurPressAmt() > 0 { b = shift_keys[b] } t := te.Entry.text index := te.Entry.cursor.index t = t[0:index] + string([]byte{b}) + t[index:] te.Entry.text = t te.Entry.cursor.index++ } else if event.Key.Id() == gin.DeleteOrBackspace { if te.Entry.cursor.index > 0 { index := te.Entry.cursor.index t := te.Entry.text te.Entry.text = t[0:index-1] + t[index:] te.Entry.cursor.index-- } } else if event.Key.Id() == gin.Left { if te.Entry.cursor.index > 0 { te.Entry.cursor.index-- } } else if event.Key.Id() == gin.Right { if te.Entry.cursor.index < len(te.Entry.text) { te.Entry.cursor.index++ } } else if event.Key.Id() == gin.Return { te.Entry.entering = false if te.Button.f != nil { te.Button.f(nil) } } else if event.Key.Id() == gin.Escape { te.Entry.entering = false te.Entry.text = te.Entry.prev te.Entry.prev = "" te.Entry.cursor.index = 0 } d := base.GetDictionary(te.Button.Text.Size) te.Entry.cursor.offset = int(d.StringWidth(te.Entry.text[0:te.Entry.cursor.index])) } } return false }
func (w *WallPanel) Respond(ui *gui.Gui, group gui.EventGroup) bool { if w.VerticalTable.Respond(ui, group) { return true } if found, event := group.FindEvent(gin.DeleteOrBackspace); found && event.Type == gin.Press { algorithm.Choose(&w.room.WallTextures, func(wt *WallTexture) bool { return wt != w.wall_texture }) w.wall_texture = nil w.prev_wall_texture = nil return true } if found, event := group.FindEvent(gin.Escape); found && event.Type == gin.Press { w.onEscape() return true } if found, event := group.FindEvent(base.GetDefaultKeyMap()["flip"].Id()); found && event.Type == gin.Press { if w.wall_texture != nil { w.wall_texture.Flip = !w.wall_texture.Flip } return true } if found, event := group.FindEvent(gin.MouseWheelVertical); found { if w.wall_texture != nil && gin.In().GetKey(gin.Space).CurPressAmt() == 0 { w.wall_texture.Rot += float32(event.Key.CurPressAmt() / 100) } } if found, event := group.FindEvent(gin.MouseLButton); found && event.Type == gin.Press { if w.wall_texture != nil { w.wall_texture.temporary = false w.wall_texture = nil } else if w.wall_texture == nil { w.wall_texture = w.textureNear(event.Key.Cursor().Point()) if w.wall_texture != nil { w.prev_wall_texture = new(WallTexture) *w.prev_wall_texture = *w.wall_texture w.wall_texture.temporary = true wx, wy := w.viewer.BoardToWindowf(w.wall_texture.X, w.wall_texture.Y) px, py := event.Key.Cursor().Point() w.drag_anchor.X = float32(px) - wx w.drag_anchor.Y = float32(py) - wy } } return true } return false }
func getKeysFromString(str string) []gin.KeyId { parts := strings.Split(str, "+") var kids []gin.KeyId for _, part := range parts { part = osSpecifyKey(part) var kid gin.KeyId switch { case len(part) == 1: // Single character - should be ascii kid = gin.KeyId(part[0]) case part == "ctrl": kid = gin.EitherControl case part == "shift": kid = gin.EitherShift case part == "alt": kid = gin.EitherAlt case part == "gui": kid = gin.EitherGui case part == "space": kid = gin.Space case part == "rmouse": kid = gin.MouseRButton case part == "lmouse": kid = gin.MouseLButton case part == "vwheel": kid = gin.MouseWheelVertical case part == "up": kid = gin.Up case part == "down": kid = gin.Down default: key := gin.In().GetKeyByName(part) if key == nil { panic(fmt.Sprintf("Unknown key '%s'", part)) } kid = key.Id() } kids = append(kids, kid) } return kids }
func (sm *StartMenu) Think(g *gui.Gui, t int64) { if sm.last_t == 0 { sm.last_t = t return } dt := t - sm.last_t sm.last_t = t if sm.mx == 0 && sm.my == 0 { sm.mx, sm.my = gin.In().GetCursor("Mouse").Point() } for _, button := range sm.buttons { button.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt) } }
func (cm *CreditsMenu) Think(g *gui.Gui, t int64) { if cm.last_t == 0 { cm.last_t = t return } dt := t - cm.last_t cm.last_t = t if cm.mx == 0 && cm.my == 0 { cm.mx, cm.my = gin.In().GetCursor("Mouse").Point() } cm.layout.Credits.Scroll.Think(dt) for _, button := range cm.buttons { button.Think(cm.region.X, cm.region.Y, cm.mx, cm.my, dt) } }
func (rc *RosterChooser) Think(ui *gui.Gui, t int64) { var dt int64 if rc.last_think != 0 { dt = t - rc.last_think } rc.last_think = t for i := range rc.options { rc.options[i].Think(dt) } max := len(rc.options) - rc.layout.Num_options if rc.focus > max { rc.focus = max } if rc.focus < 0 { rc.focus = 0 } rc.focus_pos = (1-rc.layout.Speed)*rc.focus_pos + rc.layout.Speed*float64(rc.focus) rc.mouse.X, rc.mouse.Y = gin.In().GetCursor("Mouse").Point() }
func (w *FurniturePanel) Think(ui *gui.Gui, t int64) { if w.furniture != nil { mx, my := gin.In().GetCursor("Mouse").Point() bx, by := w.RoomViewer.WindowToBoard(mx, my) f := w.furniture f.X = roundDown(bx - w.drag_anchor.x + 0.5) f.Y = roundDown(by - w.drag_anchor.y + 0.5) fdx, fdy := f.Dims() f.invalid = false if f.X < 0 { f.invalid = true } if f.Y < 0 { f.invalid = true } if f.X+fdx > w.Room.Size.Dx { f.invalid = true } if f.Y+fdy > w.Room.Size.Dy { f.invalid = true } for _, t := range w.Room.Furniture { if t == f { continue } tdx, tdy := t.Dims() r1 := image.Rect(t.X, t.Y, t.X+tdx, t.Y+tdy) r2 := image.Rect(f.X, f.Y, f.X+fdx, f.Y+fdy) if r1.Overlaps(r2) { f.invalid = true } } } w.VerticalTable.Think(ui, t) w.Room.Resize(tags.RoomSizes[w.room_size.GetComboedIndex()]) w.Room.Name = w.name.GetText() w.Room.Floor.Path = base.Path(w.floor_path.GetPath()) w.Room.Wall.Path = base.Path(w.wall_path.GetPath()) }
func (c *Chooser) Think(g *gui.Gui, t int64) { if c.last_t == 0 { c.last_t = t return } dt := t - c.last_t c.last_t = t c.layout.Options.Height = c.optionsHeight() c.layout.Options.Think(dt) if c.mx == 0 && c.my == 0 { c.mx, c.my = gin.In().GetCursor("Mouse").Point() } buttons := c.buttons if c.optionsHeight() <= c.layout.Options.Dy { buttons = c.non_scroll_buttons } for _, button := range buttons { button.Think(c.region.X, c.region.Y, c.mx, c.my, dt) } c.doOnOptions(func(index int, opt Option, data doOnOptionData) { opt.Think(data.hovered, data.selected, data.selectable, dt) }) }
func (hdt *houseRelicsTab) Think(ui *gui.Gui, t int64) { defer hdt.VerticalTable.Think(ui, t) rbx, rby := hdt.viewer.WindowToBoard(gin.In().GetCursor("Mouse").Point()) bx := roundDown(rbx - hdt.drag_anchor.x + 0.5) by := roundDown(rby - hdt.drag_anchor.y + 0.5) if hdt.temp_relic != nil { hdt.temp_relic.X = bx hdt.temp_relic.Y = by hdt.temp_relic.Dx += gin.In().GetKey(gin.Right).FramePressCount() hdt.temp_relic.Dx -= gin.In().GetKey(gin.Left).FramePressCount() if hdt.temp_relic.Dx < 1 { hdt.temp_relic.Dx = 1 } if hdt.temp_relic.Dx > 10 { hdt.temp_relic.Dx = 10 } hdt.temp_relic.Dy += gin.In().GetKey(gin.Up).FramePressCount() hdt.temp_relic.Dy -= gin.In().GetKey(gin.Down).FramePressCount() if hdt.temp_relic.Dy < 1 { hdt.temp_relic.Dy = 1 } if hdt.temp_relic.Dy > 10 { hdt.temp_relic.Dy = 10 } hdt.markTempSpawnValidity() } else { _, _, spawn_at := hdt.house.Floors[0].RoomFurnSpawnAtPos(roundDown(rbx), roundDown(rby)) if spawn_at != nil { hdt.spawn_name.SetText(spawn_at.Name) } else if hdt.spawn_name.IsBeingEdited() { hdt.typed_name = hdt.spawn_name.GetText() } else { hdt.spawn_name.SetText(hdt.typed_name) } } if hdt.temp_relic == nil && gin.In().GetKey('n').FramePressCount() > 0 && ui.FocusWidget() == nil { hdt.newSpawn() } }
func main() { defer func() { if r := recover(); r != nil { data := debug.Stack() base.Error().Printf("PANIC: %v\n", r) base.Error().Printf("PANIC: %s\n", string(data)) base.CloseLog() fmt.Printf("PANIC: %s\n", string(data)) } }() base.Log().Printf("Version %s", Version()) sys.Startup() sound.Init() render.Init() render.Queue(func() { sys.CreateWindow(10, 10, wdx, wdy) sys.EnableVSync(true) err := gl.Init() if err != nil { panic(err) } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) }) base.InitShaders() runtime.GOMAXPROCS(8) ui, err := gui.Make(gin.In(), gui.Dims{wdx, wdy}, filepath.Join(datadir, "fonts", "skia.ttf")) if err != nil { panic(err.Error()) } loadAllRegistries() // TODO: Might want to be able to reload stuff, but this is sensitive because it // is loading textures. We should probably redo the sprite system so that this // is easier to safely handle. game.LoadAllEntities() // Set up editors editors = map[string]house.Editor{ "room": house.MakeRoomEditorPanel(), "house": house.MakeHouseEditorPanel(), } for name, editor := range editors { path := base.GetStoreVal(fmt.Sprintf("last %s path", name)) path = filepath.Join(datadir, path) if path != "" { editor.Load(path) } } editor_name = "room" editor = editors[editor_name] edit_mode := false game.Restart = func() { base.Log().Printf("Restarting...") ui.RemoveChild(game_box) game_box = &lowerLeftTable{gui.MakeAnchorBox(gui.Dims{1024, 768})} err = game.InsertStartMenu(game_box) if err != nil { panic(err) } ui.AddChild(game_box) base.Log().Printf("Restarted") } game.Restart() if base.IsDevel() { ui.AddChild(base.MakeConsole()) } sys.Think() // Wait until now to create the dictionary because the render thread needs // to be running in advance. render.Queue(func() { ui.Draw() }) render.Purge() var profile_output *os.File heap_prof_count := 0 for key_map["quit"].FramePressCount() == 0 { sys.Think() render.Queue(func() { sys.SwapBuffers() ui.Draw() }) render.Purge() for _, child := range game_box.GetChildren() { if gp, ok := child.(*game.GamePanel); ok { game_panel = gp } } if base.IsDevel() { if key_map["cpu profile"].FramePressCount() > 0 { if profile_output == nil { profile_output, err = os.Create(filepath.Join(datadir, "cpu.prof")) if err == nil { err = pprof.StartCPUProfile(profile_output) if err != nil { base.Log().Printf("Unable to start CPU profile: %v\n", err) profile_output.Close() profile_output = nil } base.Log().Printf("profout: %v\n", profile_output) } else { base.Log().Printf("Unable to start CPU profile: %v\n", err) } } else { pprof.StopCPUProfile() profile_output.Close() profile_output = nil } } if key_map["heap profile"].FramePressCount() > 0 { out, err := os.Create(filepath.Join(datadir, fmt.Sprintf("heap-%d.prof", heap_prof_count))) heap_prof_count++ if err == nil { err = pprof.WriteHeapProfile(out) out.Close() if err != nil { base.Warn().Printf("Unable to write heap profile: %v", err) } } else { base.Warn().Printf("Unable to create heap profile: %v", err) } } if key_map["manual mem"].FramePressCount() > 0 { base.Log().Printf(memory.TotalAllocations()) } if key_map["game mode"].FramePressCount()%2 == 1 { base.Log().Printf("Game mode change: %t", edit_mode) if edit_mode { ui.RemoveChild(editor) ui.AddChild(game_box) } else { ui.RemoveChild(game_box) ui.AddChild(editor) } edit_mode = !edit_mode if key_map["row up"].FramePressCount() > 0 { house.Num_rows += 25 } if key_map["row down"].FramePressCount() > 0 { house.Num_rows -= 25 } if key_map["steps up"].FramePressCount() > 0 { house.Num_steps++ } if key_map["steps down"].FramePressCount() > 0 { house.Num_steps-- } if key_map["noise up"].FramePressCount() > 0 { house.Noise_rate += 10 } if key_map["noise down"].FramePressCount() > 0 { house.Noise_rate -= 10 } if key_map["foo"].FramePressCount() > 0 { house.Foo = (house.Foo + 1) % 2 } } if edit_mode { editMode() } else { gameMode() } } // Draw a cursor at the cursor - for testing an osx bug in glop. // zx, zy := gin.In().GetCursor("Mouse").Point() // render.Queue(func() { // gl.Color4ub(255, 0, 0, 255) // gl.Begin(gl.LINES) // { // gl.Vertex2i(int32(zx-25), int32(zy)) // gl.Vertex2i(int32(zx+25), int32(zy)) // gl.Vertex2i(int32(zx), int32(zy-25)) // gl.Vertex2i(int32(zx), int32(zy+25)) // } // gl.End() // }) } }
func editMode() { draggingAndZooming(editor.GetViewer()) if ui.FocusWidget() == nil { for name := range editors { if key_map[fmt.Sprintf("%s editor", name)].FramePressCount() > 0 && ui.FocusWidget() == nil { ui.RemoveChild(editor) editor_name = name editor = editors[editor_name] loadAllRegistries() editor.Reload() ui.AddChild(editor) } } if key_map["save"].FramePressCount() > 0 && chooser == nil { path, err := editor.Save() if err != nil { base.Warn().Printf("Failed to save: %v", err.Error()) } if path != "" && err == nil { base.SetStoreVal(fmt.Sprintf("last %s path", editor_name), base.TryRelative(datadir, path)) } } if key_map["load"].FramePressCount() > 0 && chooser == nil { callback := func(path string, err error) { ui.DropFocus() ui.RemoveChild(anchor) chooser = nil anchor = nil err = editor.Load(path) if err != nil { base.Warn().Printf("Failed to load: %v", err.Error()) } else { base.SetStoreVal(fmt.Sprintf("last %s path", editor_name), base.TryRelative(datadir, path)) } } chooser = gui.MakeFileChooser(filepath.Join(datadir, fmt.Sprintf("%ss", editor_name)), callback, gui.MakeFileFilter(fmt.Sprintf(".%s", editor_name))) anchor = gui.MakeAnchorBox(gui.Dims{wdx, wdy}) anchor.AddChild(chooser, gui.Anchor{0.5, 0.5, 0.5, 0.5}) ui.AddChild(anchor) ui.TakeFocus(chooser) } // Don't select tabs in an editor if we're doing some other sort of command ok_to_select := true for _, v := range key_map { if v.FramePressCount() > 0 { ok_to_select = false break } } if ok_to_select { for i := 1; i <= 9; i++ { if gin.In().GetKey(gin.KeyId('0'+i)).FramePressCount() > 0 { editor.SelectTab(i - 1) } } } } }
func (sm *OnlineMenu) Think(g *gui.Gui, t int64) { if sm.last_t == 0 { sm.last_t = t return } dt := t - sm.last_t sm.last_t = t if sm.mx == 0 && sm.my == 0 { sm.mx, sm.my = gin.In().GetCursor("Mouse").Point() } done := false for !done { select { case sm.control.in <- struct{}{}: <-sm.control.out default: done = true } } var net_id mrgnet.NetId fmt.Sscanf(base.GetStoreVal("netid"), "%d", &net_id) for i := range []*gameListBox{&sm.layout.Active, &sm.layout.Unstarted} { glb := []*gameListBox{&sm.layout.Active, &sm.layout.Unstarted}[i] select { case list := <-glb.update: glb.games = glb.games[0:0] for j := range list.Games { var b Button var name string base.Log().Printf("Adding button: %s", list.Games[j].Name) b.Text.Justification = sm.layout.Text.Justification b.Text.Size = sm.layout.Text.Size if net_id == list.Games[j].Denizens_id { name = list.Games[j].Name } else { name = list.Games[j].Name } b.Text.String = "Join!" game_key := list.Game_keys[j] active := (glb == &sm.layout.Active) in_joingame := false b.f = func(interface{}) { if in_joingame { return } in_joingame = true if active { go func() { var req mrgnet.StatusRequest req.Id = net_id req.Game_key = game_key var resp mrgnet.StatusResponse done := make(chan bool, 1) go func() { mrgnet.DoAction("status", req, &resp) done <- true }() select { case <-done: case <-time.After(5 * time.Second): resp.Err = "Couldn't connect to server." } <-sm.control.in defer func() { in_joingame = false sm.control.out <- struct{}{} }() if resp.Err != "" || resp.Game == nil { sm.layout.Error.err = resp.Err base.Error().Printf("Couldn't join game: %v", resp.Err) return } sm.ui.RemoveChild(sm) sm.ui.AddChild(MakeGamePanel("", nil, nil, game_key)) }() } else { go func() { var req mrgnet.JoinGameRequest req.Id = net_id req.Game_key = game_key var resp mrgnet.JoinGameResponse done := make(chan bool, 1) go func() { mrgnet.DoAction("join", req, &resp) done <- true }() select { case <-done: case <-time.After(5 * time.Second): resp.Err = "Couldn't connect to server." } <-sm.control.in defer func() { in_joingame = false sm.control.out <- struct{}{} }() if resp.Err != "" || !resp.Successful { sm.layout.Error.err = resp.Err base.Error().Printf("Couldn't join game: %v", resp.Err) return } sm.ui.RemoveChild(sm) sm.ui.AddChild(MakeGamePanel("", nil, nil, game_key)) }() } } if active { d := Button{} d.Text.String = "Delete!" d.Text.Justification = "right" d.Text.Size = sm.layout.Text.Size d.f = func(interface{}) { go func() { var req mrgnet.KillRequest req.Id = net_id req.Game_key = game_key var resp mrgnet.KillResponse done := make(chan bool, 1) go func() { mrgnet.DoAction("kill", req, &resp) done <- true }() select { case <-done: case <-time.After(5 * time.Second): resp.Err = "Couldn't connect to server." } <-sm.control.in if resp.Err != "" { sm.layout.Error.err = resp.Err base.Error().Printf("Couldn't kill game: %v", resp.Err) } else { algorithm.Choose(&glb.games, func(gf gameField) bool { return gf.key != req.Game_key }) } sm.control.out <- struct{}{} }() } glb.games = append(glb.games, gameField{&b, &d, name, list.Game_keys[j], list.Games[j]}) } else { glb.games = append(glb.games, gameField{&b, nil, name, list.Game_keys[j], list.Games[j]}) } } glb.Scroll.Height = int(base.GetDictionary(sm.layout.Text.Size).MaxHeight() * float64(len(list.Games))) default: } sm.hover_game = nil if (gui.Point{sm.mx, sm.my}.Inside(glb.Scroll.Region())) { for i := range glb.games { game := &glb.games[i] var region gui.Region region.X = game.join.(*Button).bounds.x region.Y = game.join.(*Button).bounds.y region.Dx = glb.Scroll.Dx region.Dy = int(base.GetDictionary(sm.layout.Text.Size).MaxHeight()) if (gui.Point{sm.mx, sm.my}.Inside(region)) { sm.hover_game = game } game.join.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt) if game.delete != nil { game.delete.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt) } } } else { for _, game := range glb.games { game.join.Think(sm.region.X, sm.region.Y, 0, 0, dt) if game.delete != nil { game.delete.Think(sm.region.X, sm.region.Y, 0, 0, dt) } } } glb.Scroll.Think(dt) } if sm.update_alpha > 0.0 && time.Now().Sub(sm.update_time).Seconds() >= 2 { sm.update_alpha = doApproach(sm.update_alpha, 0.0, dt) } for _, button := range sm.buttons { button.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt) } }