package d2gui import ( "image/color" "math" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" ) type manager struct { layout *Layout cursorAnim d2interface.Animation cursorX int cursorY int loadingAnim d2interface.Animation cursorVisible bool loading bool } func createGuiManager(inputManager d2interface.InputManager) (*manager, error) { cursorAnim, err := d2asset.LoadAnimation(d2resource.CursorDefault, d2resource.PaletteUnits) if err != nil { return nil, err } loadingAnim, err := d2asset.LoadAnimation(d2resource.LoadingScreen, d2resource.PaletteLoading) if err != nil { return nil, err } manager := &manager{ cursorAnim: cursorAnim, loadingAnim: loadingAnim, cursorVisible: true, } if err := inputManager.BindHandler(manager); err != nil { return nil, err } return manager, nil } func (m *manager) SetLayout(layout *Layout) { m.layout = layout if m.layout != nil { m.layout.AdjustEntryPlacement() } } func (m *manager) OnMouseButtonDown(event d2interface.MouseEvent) bool { if m.layout == nil { return false } return m.layout.onMouseButtonDown(event) } func (m *manager) OnMouseButtonUp(event d2interface.MouseEvent) bool { if m.layout == nil { return false } return m.layout.onMouseButtonUp(event) } func (m *manager) OnMouseMove(event d2interface.MouseMoveEvent) bool { m.cursorX = event.X() m.cursorY = event.Y() if m.layout == nil { return false } return m.layout.onMouseMove(event) } func (m *manager) render(target d2interface.Surface) error { if m.loading { if err := m.renderLoadScreen(target); err != nil { return err } } else if m.layout != nil { m.layout.SetSize(target.GetSize()) if err := m.layout.render(target); err != nil { return err } } if m.cursorVisible { if err := m.renderCursor(target); err != nil { return err } } return nil } func (m *manager) renderLoadScreen(target d2interface.Surface) error { target.Clear(color.Black) screenWidth, screenHeight := target.GetSize() animWidth, animHeight := m.loadingAnim.GetCurrentFrameSize() target.PushTranslation(screenWidth/2-animWidth/2, screenHeight/2+animHeight/2) target.PushTranslation(0, -animHeight) defer target.PopN(2) return m.loadingAnim.Render(target) } func (m *manager) renderCursor(target d2interface.Surface) error { _, height := m.cursorAnim.GetCurrentFrameSize() target.PushTranslation(m.cursorX, m.cursorY) target.PushTranslation(0, -height) defer target.PopN(2) return m.cursorAnim.Render(target) } func (m *manager) advance(elapsed float64) error { if !m.loading && m.layout != nil { if err := m.layout.advance(elapsed); err != nil { return err } } return nil } func (m *manager) showLoadScreen(progress float64) { progress = math.Min(progress, 1.0) progress = math.Max(progress, 0.0) animation := m.loadingAnim frameCount := animation.GetFrameCount() animation.SetCurrentFrame(int(float64(frameCount-1.0) * progress)) m.loading = true } func (m *manager) hideLoadScreen() { m.loading = false } func (m *manager) showCursor() { m.cursorVisible = true } func (m *manager) hideCursor() { m.cursorVisible = false } func (m *manager) clear() { m.SetLayout(nil) m.hideLoadScreen() }