GUI/Maximum window dimensions
The task is to determine the maximum height and width of a window that can fit within the physical display area of the screen without scrolling. This is effectively the screen size (not the total desktop area, which could be bigger than the screen display area) in pixels minus any adjustments for window decorations and menubars. The idea is to determine the physical display parameters for the maximum height and width of the usable display area in pixels (without scrolling). The values calculated should represent the usable desktop area of a window maximized to fit the the screen.
You are encouraged to solve this task according to the task description, using any language you may know.
Considerations
Multiple Monitors
For multiple monitors, the values calculated should represent the size of the usable display area on the monitor which is related to the task (ie the monitor which would display a window if such instructions were given).
Tiling Window Managers
For a tiling window manager, the values calculated should represent the maximum height and width of the display area of the maximum size a window can be created (without scrolling). This would typically be a full screen window (minus any areas occupied by desktop bars), unless the window manager has restrictions that prevents the creation of a full screen window, in which case the values represent the usable area of the desktop that occupies the maximum permissible window size (without scrolling).
Ada
<lang Ada>with Gtk.Main; with Glib; with Gtk.Window; use Gtk.Window; with Gtk.Enums; use Gtk.Enums; with Ada.Text_IO; use Ada.Text_IO;
procedure Max_Size is
Win : Gtk_Window; Win_W, Win_H : Glib.Gint; package Int_Io is new Integer_IO (Glib.Gint); Hid : Gtk.Main.Quit_Handler_Id;
begin
Gtk.Main.Init; Gtk_New (Win); Initialize (Win, Window_Toplevel); Maximize (Win); Show (Win); Get_Size (Win, Win_W, Win_H); Put ("Maximum dimensions of window : W "); Int_Io.Put (Win_W, Width => 4); Put (" x H "); Int_Io.Put (Win_H, Width => 4); New_Line; Hid := Gtk.Main.Quit_Add_Destroy (0, Win);
end Max_Size;</lang> Output (on a 1280 x 800 screen with Windows XP):
Maximum dimensions of window : W 1280 x H 734
BBC BASIC
<lang bbcbasic> SPI_GETWORKAREA = 48
DIM rc{l%,t%,r%,b%} SYS "SystemParametersInfo", SPI_GETWORKAREA, 0, rc{}, 0 PRINT "Maximum width = " ; rc.r% - rc.l% PRINT "Maximum height = " ; rc.b% - rc.t%</lang>
Output:
Maximum width = 1367 Maximum height = 1021
Creative Basic
<lang Creative Basic> DEF Win:WINDOW DEF Close:CHAR
DEF ScreenSizeX,ScreenSizeY:INT DEF L,T,ClientWidth,ClientHeight:INT
GETSCREENSIZE(ScreenSizeX,ScreenSizeY)
WINDOW Win,0,0,ScreenSizeX,ScreenSizeY,@MINBOX|@MAXBOX|@SIZE|@MAXIMIZED,0,"Get Client Size",MainHandler
'Left and top are always zero for this function. GETCLIENTSIZE(Win,L,T,ClientWidth,ClientHeight)
PRINT Win,"Maximum drawing area values: width is"+STR$(ClientWidth)+" and height is"+STR$(ClientHeight)+"."
WAITUNTIL Close=1
CLOSEWINDOW Win
END
SUB MainHandler
SELECT @CLASS
CASE @IDCLOSEWINDOW
Close=1
ENDSELECT
RETURN
Output: Maximum drawing area values: width is 1280 and height is 749. </lang>
EGL
To get the size of the window in a RuiHandler a JavaScript function is needed that is not natively supported by EGL. Therefore an external type is created to wrap the JavaScript function.
File 'Browser.js' in folder 'utils' in the WebContent folder of a rich UI project.
egl.defineClass( 'utils', 'Browser', { "getViewportWidth" : function () { return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; }, "getViewportHeight" : function(){ return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; } });
The external type to wrap the JavaScript functions.
ExternalType Browser type JavaScriptObject{ relativePath = "utils", javaScriptName = "Browser" } function getViewportWidth() returns (int); function getViewportHeight() returns (int); end
Usage of the Browser external type in a RuiHandler. <lang EGL> browser Browser{}; bvh int = browser.getViewportHeight(); bvw int = browser.getViewportWidth(); SysLib.writeStdout("ViewportHeight: " + bvh); SysLib.writeStdout("ViewportWidth: " + bvw); </lang> Output
ViewportHeight: 860 ViewportWidth: 1680
Gambas
Overview
In gambas, the trick to determining the maximum window size that will fit on the screen is to create a form that is maximized and then query its dimensions from within a Form_Resize() event. Note that the form can be invisible during this process, and typically we would use the main modal window (FMain in this example).
Creating the form
From with the project create a form (FMain) with the following properties set:
<lang gambas>FMain.Maximized = True FMain.Visible = False ' The form can be invisible</lang>
From within the projectview, rightclick the FMain form and select Edit class from the contextmenu. This will display a form class file (FMain.class) as follows:
<lang gambas>PUBLIC SUB _new()
END
PUBLIC SUB Form_Open()
END</lang>
Adding the form resize event
We can now add a Form_Resize() event to the class file with the necessary code to obtain the screen dimensions as follows:
<lang gambas>PUBLIC SUB Form_Resize()
PRINT "The maximum window size that can be used without scrolling is "; FMain.Width; " x "; FMain.Height
END</lang>
Haskell
<lang Haskell>import Graphics.UI.Gtk import Control.Monad (when) import Control.Monad.Trans (liftIO)
maximumWindowDimensions :: IO () maximumWindowDimensions = do
-- initialize the internal state of the GTK toolkit initGUI -- create a window window <- windowNew -- quit the application when the window is closed on window objectDestroy mainQuit -- query the size of the window when its dimensions change on window configureEvent printSize -- get the screen the window will be drawn upon screen <- windowGetScreen window -- get the size of the screen x <- screenGetWidth screen y <- screenGetHeight screen -- print the dimensions of the screen putStrLn ("The screen is " ++ show x ++ " pixels wide and " ++ show y ++ " pixels tall for an undecorated fullscreen window.") -- maximize the window and show it. printSize will then be called windowMaximize window widgetShowAll window -- run the main GTK loop. -- close the window manually. mainGUI
-- On my Xfce4 desktop, the configure_event is called three times when a -- top level window is maximized. The first time, the window size -- returned is the size prior to maximizing, and the last two times -- it is the size after maximizing. -- If the window is (un)maximized manually, the size returned is always -- the size of the unmaximized window. -- That means: either GTK or Xfce4 does not handle window maximization -- correctly, or the GTK bindings for Haskell are buggy, or there is an -- error in this program.
printSize :: EventM EConfigure Bool printSize = do
-- get the window that has been resized w <- eventWindow -- is the window maximized? s <- liftIO $ drawWindowGetState w when (WindowStateMaximized `elem` s) $ do -- get the size of the window that has been resized (x, y) <- eventSize -- print the dimensions out liftIO $ putStrLn ("The inner window region is now " ++ show x ++ " pixels wide and " ++ show y ++ " pixels tall.") return True</lang>
Icon and Unicon
Raise and query a hidden window. <lang Icon>link graphics
procedure main() # Window size
W := WOpen("canvas=hidden") dh := WAttrib("displayheight") dw := WAttrib("displaywidth") WClose(W)
write("The display size is w=",dw,", h=",dh) end</lang>
IWBASIC
<lang IWBASIC> DEF Win:WINDOW DEF Close:CHAR
DEF ScreenSizeX,ScreenSizeY:UINT DEF L,T,ClientWidth,ClientHeight:INT
GETSCREENSIZE(ScreenSizeX,ScreenSizeY)
OPENWINDOW Win,0,0,ScreenSizeX,ScreenSizeY,@MAXBOX|@MINBOX|@SIZE|@MAXIMIZED,NULL,"Get client area",&MainHandler
'Left and top are always zero for this function. GETCLIENTSIZE (Win,L,T,ClientWidth,ClientHeight)
PRINT Win,"Maximum drawing area values: width is"+STR$(ClientWidth)+" and height is"+STR$(ClientHeight)+"."
WAITUNTIL Close=1
CLOSEWINDOW WIN
END
SUB MainHandler
SELECT @MESSAGE
CASE @IDCLOSEWINDOW
Close=1
ENDSELECT
RETURN ENDSUB
Output: Maximum drawing area values: width is 1280 and height is 749. </lang>
Mathematica
Example output on a 1280x1024 system. <lang Mathematica>Differences@Transpose@SystemInformation["Devices"]1, 2, 1, 1, 2 ->Template:1260, 951</lang>
Nimrod
<lang nimrod>import
gtk2, gdk2
nimrod_init() var w = gdk2.screen_width() var h = gdk2.screen_height() echo("WxH=",w,"x",h)</lang>
- Output:
WxH=1280x800
Perl
<lang Perl> use strict; use warnings; use Tk;
sub get_size { my $mw = MainWindow->new(); return ($mw->maxsize); } </lang> get_size returns (1425,870) here.
PicoLisp
The following works on ErsatzLisp, the Java version of PicoLisp. <lang PicoLisp>(let Frame (java "javax.swing.JFrame" T "Window")
(java Frame 'setExtendedState (java (public "javax.swing.JFrame" 'MAXIMIZED_BOTH)) ) (java Frame 'setVisible T) (wait 200) (let Size (java (java Frame 'getContentPane) 'getSize) (prinl "Width: " (java (public Size 'width))) (prinl "Height: " (java (public Size 'height))) ) (java Frame 'dispose) )</lang>
Output (on a 1024x768 screen):
Width: 1010 Height: 735
PureBasic
<lang PureBasic>If OpenWindow(0, 0, 0, 5, 5, "", #PB_Window_Maximize + #PB_Window_Invisible)
maxX = WindowWidth(0) maxY = WindowHeight(0) CloseWindow(0) MessageRequester("Result", "Maximum Window Width: " + Str(maxX) + ", Maximum Window Height: " + Str(maxY))
EndIf</lang> Sample output for a screen area 1600 x 1200:
Maximum Window Width: 1600, Maximum Window Height: 1181
Racket
<lang racket>
- lang racket/gui
(define-values [W H]
(let ([f (new frame% [label "test"])]) (begin0 (send* f (maximize #t) (show #t) (get-client-size)) (send f show #f))))
(printf "~ax~a\n" W H) </lang>
Run BASIC
Run Basic uses javaScript to return the width of the browser window. IE browser uses different functions than everyone else. So you write code for the world, and also for IE <lang runbasic> html "<INPUT TYPE='HIDDEN' id='winHigh' name='winHigh' VALUE='";winHigh;"'></input>" html "<INPUT TYPE='HIDDEN' id='winWide' name='winWide' VALUE='";winWide;"'></input>"
html "<script> </script> "</lang>
Tcl
<lang tcl>package require Tk proc maxSize {} {
# Need a dummy window; max window can be changed by scripts set top .__defaultMaxSize__ if {![winfo exists $top]} { toplevel $top wm withdraw $top } # Default max size of window is value we want return [wm maxsize $top]
}</lang>
On this system, that returns 1440 836
. Further discussion of related matters, including platform limitations, is on the Tcler's Wiki.
Visual Basic
Method 1
The first method involves querying the screen dimensions and then subtracting pixels used by the frame and desktop bars:
<lang vb>TYPE syswindowstru
screenheight AS INTEGER screenwidth AS INTEGER maxheight AS INTEGER maxwidth AS INTEGER
END TYPE
DIM syswindow AS syswindowstru
' Determine the height and width of the screen
syswindow.screenwidth = Screen.Width / Screen.TwipsPerPixelX syswindow.screenheight=Screen.Height / Screen.TwipsPerPixelY
' Make adjustments for window decorations and menubars</lang>
Method 2
The alternative method is to create a form that is maximized and then query its dimensions (similar to the method used in gambas).