Window management

From Rosetta Code
Task
Window management
You are encouraged to solve this task according to the task description, using any language you may know.

Treat windows or at least window identities as first class objects.

  • Store window identities in variables, compare them for equality.
  • Provide examples of performing some of the following:
    • hide, show, close, minimize, maximize, move, and resize a window.

The window of interest may or may not have been created by your program.

AutoHotkey

<lang AutoHotkey>F1::  ;; when user hits the F1 key, do the following WinGetTitle, window, A  ; get identity of active window into a variable WinMove, %window%, , 100, 100, 800, 800 ; move window to coordinates, 100, 100

                                       ; and change size to 800 x 800 pixels

sleep, 2000 WinHide, % window  ; hide window TrayTip, hidden, window is hidden, 2 sleep, 2000 WinShow, % window  ; show window again loop, {

 inputbox, name, what was the name of your window? 
 if (name = window) ; compare window variables for equality
 {
   msgbox you got it
   break
 }
else try again

} WinClose, % window return</lang>

HicEst

<lang hicest>CHARACTER title="Rosetta Window_management" REAL :: w=-333, h=25, x=1, y=0.5 ! pixels < 0, relative window size 0...1, script character size > 1

 WINDOW(WINdowhandle=wh, Width=w, Height=h, X=x, Y=y, TItle=title) ! create, on return size/pos VARIABLES are set to script char
 WINDOW(WIN=wh, MINimize)    ! minimize
 WINDOW(WIN=wh, SHowNormal)  ! restore
 WINDOW(WIN=wh, X=31, Y=7+4) !<-- move upper left here (col 31, row 7 + ~4 rows for title, menus, toolbar. Script window in upper left screen)
 WINDOW(WIN=wh, MAXimize)    ! maximize (hides the script window)
 WINDOW(Kill=wh)             ! close

END</lang>

Icon and Unicon

The demo program opens three windows, one with a running commentary on the action. <lang Icon>link graphics

procedure main()

  Delay := 3000
  W1 := open("Window 1","g","resize=on","size=400,400","pos=100,100","bg=black","fg=red") |
        stop("Unbale to open window 1")
  W2 := open("Window 2","g","resize=on","size=400,400","pos=450,450","bg=blue","fg=yellow") |
        stop("Unbale to open window 2")
  W3 := open("Window 3","g","resize=on","size=400,400","pos=600,150","bg=orange","fg=black") |
        stop("Unbale to open window 3")
  WWrite(W3,"Opened three windows")
  
  WWrite(W3,"Window 1&2 with rectangles")
  every Wx := W1 | W2 | W3 do
     if Wx ~=== W3 then 
        FillRectangle(Wx,50,50,100,100)     
  
  delay(Delay) 
  WWrite(W3,"Window 1 rasied")   
  Raise(W1)

  delay(Delay)
  WWrite(W3,"Window 2 hidden")   
  WAttrib(W2,"canvas=hidden")
  
  delay(Delay) 
  WWrite(W3,"Window 2 maximized")    
  WAttrib(W2,"canvas=maximal")
  Raise(W3)
  delay(Delay)   
  WWrite(W3,"Window 2 restored & resized") 
  WAttrib(W2,"canvas=normal")
  WAttrib(W2,"size=600,600")
  
  delay(Delay)
  WWrite(W3,"Window 2 moveded")    
  WAttrib(W2,"posx=700","posy=300")
  
  delay(Delay) 
  WWrite(W3,"Window 2 minimized")     
  WAttrib(W2,"canvas=iconic")  
  
  delay(Delay) 
  WWrite(W3,"Window 2 restored")
  WAttrib(W2,"canvas=normal")  # restore as maximal, possible bug
  
  delay(Delay)
  WWrite(W3,"Enter Q or q here to quit") 
  WDone(W3)         

end</lang>

graphics.icn provides graphics

Oz

<lang Mathematica>windows=Notebooks[];(*Find*) SetOptions[windows1,Visible->False];(*Hide*) SetOptions[windows1,Visible->True];(*Show*) SetOptions[windows1,WindowMargins->{{0,Automatic},{0,Automatic}}];(*Move*) SetOptions[windows1,WindowSize->{100,100}];(*Resize*) </lang>



Oz

We use QTk, Oz' default GUI toolkit. QTk takes a declarative description of the GUI and from this creates objects which represent the GUI parts. So windows are represented by objects and thus have an identity.

We create two windows with a simple GUI. The user can use each window to send messages to the window or its neighboring window. (Sending messages is the same as 'calling methods' in Oz.)

We also wrap the Window objects in a procedure in order to extend their functionality. This is interesting because it shows how to extend an object's interface even when we don't have control over object creation.

<lang oz>declare

 [QTk] = {Module.link ['x-oz://system/wp/QTk.ozf']}
 %% The messages that can be sent to the windows.
 WindowActions =
 [hide show close
  iconify deiconify
  maximize restore
  set(minsize:minsize(width:400 height:400))
  set(minsize:minsize(width:200 height:200))
  set(geometry:geometry(x:0 y:0))
  set(geometry:geometry(x:500 y:500))
 ]
 %% Two windows, still uninitialized.
 Windows = windows(window1:_
                   window2:_)
 fun {CreateWindow}
    Message = {NewCell WindowActions.1}
    ReceiverName = {NewCell {Arity Windows}.1}
    fun {ButtonText}
       "Send"#"  "#{ValueToString @Message}#"  to  "#@ReceiverName
    end
    Button
    Desc =
    td(title:"Window Management"
       lr(listbox(init:{Arity Windows}
                  glue:nswe
                  tdscrollbar:true
                  actionh:proc {$ W}
                             ReceiverName := {GetSelected W}
                             {Button set(text:{ButtonText})}
                          end
                 )
          listbox(init:{Map WindowActions ValueToString}
                  glue:nswe
                  tdscrollbar:true
                  actionh:proc {$ A}
                             Message := {GetSelected A}
                             {Button set(text:{ButtonText})}
                          end
                 )
          glue:nswe
         )
       button(text:{ButtonText}
              glue:we
              handle:Button
              action:proc {$}
                        {Windows.@ReceiverName @Message}
                     end
             )
      )
    Window = {Extend {QTk.build Desc}}
 in
    {Window show}
    Window
 end
 %% Adds two methods to a toplevel instance.
 %% For maximize and restore we have to interact directly with Tk
 %% because that functionality is not part of the QTk library.
 fun {Extend Toplevel}
    proc {$ A}
       case A of maximize then
          {Tk.send wm(state Toplevel zoomed)}
       [] restore then
          {Tk.send wm(state Toplevel normal)}
       else
          {Toplevel A}
       end
    end
 end
 %% Returns the current entry of a listbox
 %% as an Oz value.
 fun {GetSelected LB}
    Entries = {LB get($)}
    Index = {LB get(firstselection:$)}
 in
    {Compiler.virtualStringToValue {Nth Entries Index}}
 end
 fun {ValueToString V}
    {Value.toVirtualString V 100 100}
 end

in

 {Record.forAll Windows CreateWindow}</lang>

PicoLisp

The following works on ErsatzLisp, the Java version of PicoLisp. <lang PicoLisp>$ ersatz/pil +

(setq
  JFrame         "javax.swing.JFrame"
  MAXIMIZED_BOTH (java (public JFrame 'MAXIMIZED_BOTH))
  ICONIFIED      (java (public JFrame 'ICONIFIED))
  Win            (java JFrame T "Window") )

-> $JFrame

  1. Compare for equality
(== Win Win)

-> T

  1. Set window visible

(java Win 'setLocation 100 100) (java Win 'setSize 400 300) (java Win 'setVisible T)

  1. Hide window

(java Win 'hide)

  1. Show again

(java Win 'setVisible T)

  1. Move window

(java Win 'setLocation 200 200)

  1. Iconify window

(java Win 'setExtendedState

  (| (java (java Win 'getExtendedState)) ICONIFIED) )
  1. De-conify window

(java Win 'setExtendedState

  (& (java (java Win 'getExtendedState)) (x| (hex "FFFFFFFF") ICONIFIED)) )
  1. Maximize window

(java Win 'setExtendedState

  (| (java (java Win 'getExtendedState)) MAXIMIZED_BOTH) )
  1. Close window

(java Win 'dispose)</lang>

PureBasic

<lang PureBasic>;- Create a linked list to store created windows. NewList Windows() Define i, j, dh, dw, flags, err$, x, y

- Used sub-procedure to simplify the error handling

Procedure HandleError(Result, Text.s,ErrorLine=0,ExitCode=0)

 If Not Result
   MessageRequester("Error",Text)
   End ExitCode
 EndIf
 ProcedureReturn Result

EndProcedure

- Window handling procedures

Procedure Minimize(window)

 SetWindowState(window,#PB_Window_Minimize)

EndProcedure

Procedure Normalize(window)

 SetWindowState(window,#PB_Window_Normal)

EndProcedure

- Get enviroment data

HandleError(ExamineDesktops(), "Failed to examine you Desktop.") dh=HandleError(DesktopHeight(0),"Could not retrieve DesktopHight")/3 dw=HandleError(DesktopWidth(0), "Could not retrieve DesktopWidth")/3

- Now, creating 9 windows

flags=#PB_Window_SystemMenu err$="Failed to open Window" For i=0 To 8

 j=HandleError(OpenWindow(#PB_Any,i*10,i*10+30,10,10,Str(i),flags),err$)
 SmartWindowRefresh(j, 1) 
 AddElement(Windows())
 Windows()=j

Next i Delay(1000)

- Call a sub-routine for each Window stored in the list.

ForEach Windows()

 Minimize(Windows())

Next Delay(1000)

- and again

ForEach Windows()

 Normalize(Windows())

Next Delay(1000)

- Spread them evenly

ForEach Windows()

 ResizeWindow(Windows(),x*dw,y*dh,dw-15,dh-35)
 x+1
 If x>2
   x=0: y+1
 EndIf

Next Delay(2000)

End</lang>

Python

Works with: Python version 3.x
Library: tkinter

Using the tkinter GUI: <lang Python> from tkinter import * import tkinter.messagebox

def maximise(): """get screenwidth and screenheight, and resize window to that size. Also move to 0,0""" root.geometry("{}x{}+{}+{}".format(root.winfo_screenwidth(), root.winfo_screenheight(), 0, 0))

def minimise(): """Iconify window to the taskbar. When reopened, the window is unfortunately restored to its original state, NOT its most recent state.""" root.iconify()

def delete(): """create a modal dialog. If answer is "OK", quit the program""" if tkinter.messagebox.askokcancel("OK/Cancel","Are you sure?"): root.quit()

root = Tk()

mx=Button(root,text="maximise",command=maximise) mx.grid() mx.bind(maximise)

mn=Button(root,text="minimise",command=minimise) mn.grid() mn.bind(minimise)

  1. catch exit events, including "X" on title bar.

root.protocol("WM_DELETE_WINDOW",delete)

mainloop() </lang>

Tcl

Library: Tk

<lang tcl>package require Tk

  1. How to open a window

proc openWin {} {

   global win
   if {[info exists win] && [winfo exists $win]} {
       # Already existing; just reset
       wm deiconify $win
       wm state $win normal
       return
   }
   catch {destroy $win} ;# Squelch the old one
   set win [toplevel .t]
   pack [label $win.label -text "This is the window being manipulated"] \
       -fill both -expand 1

}

  1. How to close a window

proc closeWin {} {

   global win
   if {[info exists win] && [winfo exists $win]} {
       destroy $win
   }

}

  1. How to minimize a window

proc minimizeWin {} {

   global win
   if {[info exists win] && [winfo exists $win]} {
       wm state $win iconic
   }

}

  1. How to maximize a window

proc maximizeWin {} {

   global win
   if {[info exists win] && [winfo exists $win]} {
       wm state $win zoomed
       catch {wm attribute $win -zoomed 1} ;# Hack for X11
   }

}

  1. How to move a window

proc moveWin {} {

   global win
   if {[info exists win] && [winfo exists $win]} {
       scan [wm geometry $win] "%dx%d+%d+%d" width height x y
       wm geometry $win +[incr x 10]+[incr y 10]
   }

}

  1. How to resize a window

proc resizeWin {} {

   global win
   if {[info exists win] && [winfo exists $win]} {
       scan [wm geometry $win] "%dx%d+%d+%d" width height x y
       wm geometry $win [incr width 10]x[incr height 10]
   }

}

grid [label .l -text "Window handle:"] [label .l2 -textvariable win] grid [button .b1 -text "Open/Reset" -command openWin] - grid [button .b2 -text "Close" -command closeWin] - grid [button .b3 -text "Minimize" -command minimizeWin] - grid [button .b4 -text "Maximize" -command maximizeWin] - grid [button .b5 -text "Move" -command moveWin] - grid [button .b6 -text "Resize" -command resizeWin] -</lang>