ui: Add fuctions to maximize or minimize the window

This change adds these functions:

  * MaximizeWindow
  * IsWindowMaximized
  * MinimizeWIndow
  * IsWindowMinimized
  * RestoreWindow

Fixes #994
This commit is contained in:
Hajime Hoshi 2020-03-21 19:26:28 +09:00
parent 60c6626235
commit f317f3b5fd
8 changed files with 205 additions and 1 deletions

View File

@ -55,10 +55,12 @@ var (
flagLegacy = flag.Bool("legacy", false, "use the legacy API")
flagFullscreen = flag.Bool("fullscreen", false, "fullscreen")
flagResizable = flag.Bool("resizable", false, "make the window resizable")
flagWindowPosition = flag.String("windowposition", "", "window position (e.g., 100,200)")
flagScreenTransparent = flag.Bool("screentransparent", false, "screen transparent")
flagAutoAdjusting = flag.Bool("autoadjusting", false, "make the game screen auto-adjusting")
flagFloating = flag.Bool("floating", false, "make the window floating")
flagMaximize = flag.Bool("maximize", false, "maximize the window")
)
func init() {
@ -226,6 +228,9 @@ func (g *game) Update(screen *ebiten.Image) error {
if inpututil.IsKeyJustPressed(ebiten.KeyR) {
resizable = !resizable
}
maximize := inpututil.IsKeyJustPressed(ebiten.KeyM)
minimize := inpututil.IsKeyJustPressed(ebiten.KeyI)
restore := inpututil.IsKeyJustPressed(ebiten.KeyE)
if toUpdateWindowSize {
if *flagLegacy {
@ -245,6 +250,15 @@ func (g *game) Update(screen *ebiten.Image) error {
ebiten.SetWindowDecorated(decorated)
ebiten.SetWindowPosition(positionX, positionY)
ebiten.SetWindowFloating(floating)
if maximize {
ebiten.MaximizeWindow()
}
if minimize {
ebiten.MinimizeWindow()
}
if restore {
ebiten.RestoreWindow()
}
if !*flagLegacy {
// A resizable window is available only with RunGame.
ebiten.SetWindowResizable(resizable)
@ -279,6 +293,18 @@ func (g *game) Update(screen *ebiten.Image) error {
tpsStr = fmt.Sprintf("%d", t)
}
var lines []string
if !ebiten.IsWindowMaximized() {
lines = append(lines, "Press M key to maximize the window")
}
if !ebiten.IsWindowMinimized() {
lines = append(lines, "Press I key to minimize the window")
}
if ebiten.IsWindowMaximized() || ebiten.IsWindowMinimized() {
lines = append(lines, "Press E key to restore the window from maximized/minimized state")
}
msgM := strings.Join(lines, "\n")
var msgS string
var msgR string
if *flagLegacy {
@ -302,12 +328,13 @@ Press T key to switch TPS (ticks per second)
Press D key to switch the window decoration (only for desktops)
Press L key to switch the window floating state (only for desktops)
%s
%s
IsFocused?: %s
Windows Position: (%d, %d)
Cursor: (%d, %d)
TPS: Current: %0.2f / Max: %s
FPS: %0.2f
Device Scale Factor: %0.2f`, msgS, msgR, fg, wx, wy, cx, cy, ebiten.CurrentTPS(), tpsStr, ebiten.CurrentFPS(), ebiten.DeviceScaleFactor())
Device Scale Factor: %0.2f`, msgS, msgM, msgR, fg, wx, wy, cx, cy, ebiten.CurrentTPS(), tpsStr, ebiten.CurrentFPS(), ebiten.DeviceScaleFactor())
ebitenutil.DebugPrint(screen, msg)
return nil
}
@ -370,9 +397,15 @@ func main() {
if *flagFullscreen {
ebiten.SetFullscreen(true)
}
if *flagResizable {
ebiten.SetWindowResizable(true)
}
if *flagFloating {
ebiten.SetWindowFloating(true)
}
if *flagMaximize {
ebiten.MaximizeWindow()
}
if *flagAutoAdjusting {
if *flagLegacy {
log.Println("-autoadjusting flag cannot work with -legacy flag")

View File

@ -71,6 +71,13 @@ type Window interface {
IsFloating() bool
SetFloating(floating bool)
Maximize()
IsMaximized() bool
Minimize()
IsMinimized() bool
SetIcon(iconImages []image.Image)
SetTitle(title string)
Restore()
}

View File

@ -79,6 +79,8 @@ const (
Decorated = Hint(0x00020005)
Floating = Hint(0x00020007)
Focused = Hint(0x00020001)
Iconified = Hint(0x00020002)
Maximized = Hint(0x00020008)
Resizable = Hint(0x00020003)
TransparentFramebuffer = Hint(0x0002000A)
Visible = Hint(0x00020004)

View File

@ -130,10 +130,22 @@ func (w *Window) GetSize() (width, height int) {
return w.w.GetSize()
}
func (w *Window) Iconify() {
w.w.Iconify()
}
func (w *Window) MakeContextCurrent() {
w.w.MakeContextCurrent()
}
func (w *Window) Maximize() {
w.w.Maximize()
}
func (w *Window) Restore() {
w.w.Restore()
}
func (w *Window) SetCharModsCallback(cbfun CharModsCallback) (previous CharModsCallback) {
var gcb glfw.CharModsCallback
if cbfun != nil {

View File

@ -166,11 +166,21 @@ func (w *Window) GetSize() (int, int) {
return int(width), int(height)
}
func (w *Window) Iconify() {
glfwDLL.call("glfwIconifyWindow", w.w)
panicError()
}
func (w *Window) MakeContextCurrent() {
glfwDLL.call("glfwMakeContextCurrent", w.w)
panicError()
}
func (w *Window) Maximize() {
glfwDLL.call("glfwMaximizeWindow", w.w)
panicError()
}
func (w *Window) SetCharModsCallback(cbfun CharModsCallback) (previous CharModsCallback) {
var gcb uintptr
if cbfun != nil {

View File

@ -67,6 +67,7 @@ type UserInterface struct {
initWindowWidthInDP int
initWindowHeightInDP int
initWindowFloating bool
initWindowMaximized bool
initScreenTransparent bool
initIconImages []image.Image
@ -348,6 +349,19 @@ func (u *UserInterface) setInitWindowFloating(floating bool) {
u.m.Unlock()
}
func (u *UserInterface) isInitWindowMaximized() bool {
u.m.Lock()
f := u.initWindowMaximized
u.m.Unlock()
return f
}
func (u *UserInterface) setInitWindowMaximized(floating bool) {
u.m.Lock()
u.initWindowMaximized = floating
u.m.Unlock()
}
// toDeviceIndependentPixel must be called from the main thread.
func (u *UserInterface) toDeviceIndependentPixel(x float64) float64 {
return x / u.glfwScale()
@ -648,6 +662,12 @@ func (u *UserInterface) run(context driver.UIContext) error {
}
glfw.WindowHint(glfw.Floating, floating)
maximized := glfw.False
if u.isInitWindowMaximized() {
maximized = glfw.True
}
glfw.WindowHint(glfw.Maximized, maximized)
// Set the window visible explicitly or the application freezes on Wayland (#974).
if os.Getenv("WAYLAND_DISPLAY") != "" {
glfw.WindowHint(glfw.Visible, glfw.True)

View File

@ -116,6 +116,63 @@ func (w *window) SetFloating(floating bool) {
})
}
func (w *window) IsMaximized() bool {
if !w.ui.isRunning() {
return w.ui.isInitWindowMaximized()
}
var v bool
_ = w.ui.t.Call(func() error {
v = w.ui.window.GetAttrib(glfw.Maximized) == glfw.True
return nil
})
return v
}
func (w *window) Maximize() {
if !w.ui.isRunning() {
w.ui.setInitWindowMaximized(true)
return
}
_ = w.ui.t.Call(func() error {
w.ui.window.Maximize()
return nil
})
}
func (w *window) IsMinimized() bool {
if !w.ui.isRunning() {
return false
}
var v bool
_ = w.ui.t.Call(func() error {
v = w.ui.window.GetAttrib(glfw.Iconified) == glfw.True
return nil
})
return v
}
func (w *window) Minimize() {
if !w.ui.isRunning() {
// Do nothing
return
}
_ = w.ui.t.Call(func() error {
w.ui.window.Iconify()
return nil
})
}
func (w *window) Restore() {
if !w.ui.isRunning() {
// Do nothing
return
}
_ = w.ui.t.Call(func() error {
w.ui.window.Restore()
return nil
})
}
func (w *window) Position() (int, int) {
if !w.ui.isRunning() {
panic("glfw: WindowPosition can't be called before the main loop starts")

View File

@ -236,6 +236,8 @@ func SetWindowSize(width, height int) {
// IsWindowFloating reports whether the window is always shown above all the other windows.
//
// IsWindowFloating returns false on browsers and mobiles.
//
// IsWindowFloating is concurrent-safe.
func IsWindowFloating() bool {
if w := uiDriver().Window(); w != nil {
@ -246,9 +248,70 @@ func IsWindowFloating() bool {
// SetWindowFloating sets the state whether the window is always shown above all the other windows.
//
// SetWindowFloating does nothing on browsers or mobiles.
//
// SetWindowFloating is concurrent-safe.
func SetWindowFloating(float bool) {
if w := uiDriver().Window(); w != nil {
w.SetFloating(float)
}
}
// MaximizeWindow maximizes the window.
//
// On some environments like macOS, MaximizeWindow requres that the window is resizable.
//
// MaximizeWindow does nothing on browsers or mobiles.
//
// MaximizeWindow is concurrent-safe.
func MaximizeWindow() {
if w := uiDriver().Window(); w != nil {
w.Maximize()
}
}
// IsWindowMaximized reports whether the window is maximized or not.
//
// IsWindowMaximized always returns false on browsers and mobiles.
//
// IsWindowMaximized is concurrent-safe.
func IsWindowMaximized() bool {
if w := uiDriver().Window(); w != nil {
return w.IsMaximized()
}
return false
}
// MinimizeWindow minimizes the window.
//
// If the main loop does not start yet, MinimizeWindow does nothing.
//
// MinimizeWindow does nothing on browsers or mobiles.
//
// MinimizeWindow is concurrent-safe.
func MinimizeWindow() {
if w := uiDriver().Window(); w != nil {
w.Minimize()
}
}
// IsWindowMinimized reports whether the window is minimized or not.
//
// IsWindowMinimized always returns false on browsers and mobiles.
//
// IsWindowMinimized is concurrent-safe.
func IsWindowMinimized() bool {
if w := uiDriver().Window(); w != nil {
return w.IsMinimized()
}
return false
}
// RestoreWindow restores the window from its maximized or minimized state.
//
// RestoreWindow is concurrent-safe.
func RestoreWindow() {
if w := uiDriver().Window(); w != nil {
w.Restore()
}
}