Graphics helper functions
Written by Nick Gammon - July 2008. Updated September 2010.
On this page:
- DrawingOrder
- GetDeviceCaps
- GetSysColor
- Redraw
- Repaint
- SetBackgroundColour
- SetBackgroundImage
- SetCursor
- SetForegroundImage
- TextRectangle
- utils.getfontfamilies
See also:
- Introduction
- Creating miniwindows
- Drawing shapes
- Drawing text
- Drawing images
- Hotspots
- Blending images
Set output window background colour
SetBackgroundColour function prototype:
long SetBackgroundColour(long Colour);
This changes the default background colour of the output window. This is intended to be used to make "mood" changes to the output window. For example, if you are currently playing in a watery zone, the background colour could change from black to a deep blue.
You simply specify the RGB code for the desired colour, or the constant 0xFFFFFFFF to indicate to use the default behaviour. Normally MUSHclient draws the background in ANSI colour "normal black". If you have set a colour, then any time the background colour for text would have been "normal black", then the background is not drawn and thus the background colour you chose is allowed to stay.
Example of setting background colour
SetBackgroundColour (0x000055)
You should exercise caution in your choice of background colour. Too bright a background and the normal white text will be virtually invisible. Probably you want quite a dark colour, as in the example above.
Set output window background image
SetBackgroundImage function prototype:
long SetBackgroundImage(BSTR FileName, short Mode);
This sets a background image for output window. The text in the output window is drawn on top of this. If the image does not completely fill the window, the background colour is visible beneath it.
- FileName - the disk file to load the image from. It should be a BMP or PNG file, not a GIF, TIF or other file type.
- Mode - a number indicating where you want the image positioned on the screen. Whenever the screen is resized or redrawn the contents of the image are drawn in the requested position:
Value Purpose Lua symbol 0 Stretch to output view size miniwin.pos_stretch_to_view 1 Stretch with aspect ratio miniwin.pos_stretch_to_view_with_aspect 2 Strech to owner size miniwin.pos_stretch_to_owner 3 Stretch with aspect ratio miniwin.pos_stretch_to_owner_with_aspect 4 Top left miniwin.pos_top_left 5 Center left-right at top miniwin.pos_top_center 6 Top right miniwin.pos_top_right 7 On right, center top-bottom miniwin.pos_center_right 8 On right, at bottom miniwin.pos_bottom_right 9 Center left-right at bottom miniwin.pos_bottom_center 10 On left, at bottom miniwin.pos_bottom_left 11 On left, center top-bottom miniwin.pos_center_left 12 Centre all miniwin.pos_center_all 13 Tile miniwin.pos_tile The "stretch" versions expand or contract the image to fit the output window. If you use "with aspect ratio" the image fits exactly top-to-bottom, and may be clipped left-right to preserve the original aspect ratio.
The difference beteween "output view" and "owner size" is that with "output view" (modes 0 and 1) the image will tend to flicker annoyingly if you have automatic resizing of the command window active (as this will make the output window size change, and thus the image size will keep changing) .
Example of setting a background image
SetBackgroundImage ("wolf.bmp", 0)
You should exercise caution in your choice of background image. Only a subdued image will let the text appear over it without being distracting. Alternatively a subtle logo in the top right-hand corner might be acceptable.
Set output window foreground image
SetForegroundImage function prototype:
long SetForegroundImage(BSTR FileName, short Mode);
This sets a foreground image for output window. The text in the output window is drawn under this. The function arguments are the same as for SetBackgroundImage described above so they won't be repeated here.
Example of setting a foreground image
SetForegroundImage ("wolf.bmp", 6)
Obviously if you choose a very large image, or stretch to fit the window, the text arriving from the MUD will be completely invisible.
Set MUD output text rectangle size
TextRectangle function prototype:
long TextRectangle(long Left, long Top, long Right, long Bottom, long BorderOffset, long BorderColour, long BorderWidth, long OutsideFillColour, long OutsideFillStyle);
This reduces the rectangle in which normal MUD output is displayed, from the entire output window, to the subset specified. This can be used to make a "desktop effect" where you have room on all sides for miniwindows to be placed. A border can be drawn at the edge of the rectangle to make it obvious where the text ends, to help in resizing the window. The text is clipped to be within the text rectangle.
- Left, Top, Right, Bottom - describes the rectangle in which the text is drawn. If 0,0,0,0 is specified, text is drawn "normally" to the borders of the output window.
- BorderOffset - the offset in pixels between the edge of the text, and the border. You can specify a few pixels here so that the text is not jammed up against the border.
- BorderColour - the colour to draw the border in (RGB value).
- BorderWidth - the width of the border - make zero for no border.
- OutsideFillColour - the brush colour to fill the area outside the text rectangle.
- OutsideFillStyle - the brush mode to use for the outside fill. See Brush parameters for a description of the various modes. In the example below, mode 8 (fine pattern) was used.
Example of making a text rectangle
TextRectangle(50, -- left
100, -- top
50 + GetInfo (213) * 80, -- 50 + width for 80 characters
-100, -- 100 pixels from the bottom
5, -- BorderOffset,
ColourNameToRGB ("gray"), -- BorderColour,
2, -- BorderWidth,
ColourNameToRGB ("silver"), -- OutsideFillColour,
8) -- OutsideFillStyle (fine hatch)
Obviously you don't want too small a rectangle, or it will be hard or impossible to see the MUD output. You could use 'GetInfo (213) * 80' to calculate a suitable width (output font width, multiplied by 80, to allow for 80 columns).
Image and window drawing order
Now that MUSHclient is drawing a whole heap of foreground and background images, it is helpful to see what order they are done in. The graphic below explains it:
You can have both foreground and background window images, plus multiple miniwindows, both behind and in front of the MUD text. The miniwindows themselves are drawn in ascending alphabetical order by miniwindow name, thus the ones drawn later will be on top, as they are drawn on top of the ones earlier down the list.
Get display device capabilities
GetDeviceCaps function prototype:
long GetDeviceCaps(long Index);
This asks Windows for the capability of your output screen. The index specifies which attribute you are interested in, and it returns a number corresponding to that. Some useful indices are as follows:
- 0 : Device driver version
- 2 : Device classification
- 4 : Horizontal size in millimeters
- 6 : Vertical size in millimeters
- 8 : Horizontal width in pixels
- 10 : Vertical height in pixels
- 12 : Number of bits per pixel
- 14 : Number of planes
- 16 : Number of brushes the device has
- 18 : Number of pens the device has
- 20 : Number of markers the device has
- 22 : Number of fonts the device has
- 24 : Number of colors the device supports
- 26 : Size required for device descriptor
- 28 : Curve capabilities
- 30 : Line capabilities
- 32 : Polygonal capabilities
- 34 : Text capabilities
- 36 : Clipping capabilities
- 38 : Bitblt capabilities
- 40 : Length of the X leg
- 42 : Length of the Y leg
- 44 : Length of the hypotenuse
- 45 : Shading and blending caps
- 88 : Logical pixels/inch in X
- 90 : Logical pixels/inch in Y
- 104 : Number of entries in physical palette
- 106 : Number of reserved entries in palette
- 108 : Actual color resolution
- 116 : Current vertical refresh rate of the display device (for displays only) in Hz
- 117 : Horizontal width of entire desktop in pixels
- 118 : Vertical height of entire desktop in pixels
- 119 : Preferred blt alignment
Example of getting device capabilities
print (GetDeviceCaps (8)) --> 1920 (horizontal width)
Get available fonts
This lets you find the names of all the fonts installed on your current system. It is a Lua-only script function. The intention here is for scripts to decide if a font is available, before setting the output or command window to use that font.
Example of getting fonts
t = utils.getfontfamilies ()
for font in pairs (t) do
print (font)
end
Output
Lucida Console
Comic Sans MS
Georgia
Mangal
WST_Engl
Wingdings
Sylfaen
Franklin Gothic Medium
Courier
... etc ...
Get system colours
GetSysColor function prototype:
long GetSysColor(long Index);
This function directly calls GetSysColor in Windows. It returns the colour used by various items as currently configured in Windows, based on the selector (Index), as follows:
- Scrollbar = 0
- Background = 1
- Active caption = 2
- Inactive caption = 3
- Menu = 4
- Window = 5
- Window frame = 6
- Menu text = 7
- Window text = 8
- Caption text = 9
- Active border = 10
- Inactive border = 11
- Application workspace = 12
- Highlight = 13
- Highlight text = 14
- Button face = 15
- Button shadow = 16
- Gray text = 17
- Button text = 18
- Inactive caption text = 19
- Button highlight = 20
- 3D dark shadow = 21
- 3D light = 22
- Info text = 23
- Info bk = 24
Schedule output window redraw
Redraw function prototype:
void Redraw();
This function schedules the output window to be redrawn. You should call this after changing the contents of miniwindows. The function WindowShow calls Redraw automatically. Note that the main window is not actually redrawn at this point, however it is scheduled for redraw next time through the main event loop.
Force output window redraw
Repaint function prototype:
void Repaint();
This function forces the output window to be redrawn. This should not normally be called, as the window will be redrawn at the appropriate time through the main "event loop". Unnecessary calls to Repaint will slow the program down. However for "animation" situations (like moving an image over a map) there may be times when you actually want the window redrawn, between "frames". In this case, you could call Repaint to force an immediate redraw.
Change the shape of the mouse pointer
SetCursor function prototype:
long SetCursor(long Cursor);
This function lets you change the shape of the cursor during a hotspot drag operation.
The argument a number which indicates what shape the mouse pointer is to take when as follows:
| Value | Purpose | Lua symbol |
|---|---|---|
| -1 | No cursor | |
| 0 | Arrow | |
| 1 | Hand | |
| 2 | I-beam | |
| 3 | + symbol | |
| 4 | Wait (hour-glass) | |
| 5 | Up arrow | |
| 6 | Arrow nw-se | |
| 7 | Arrow ne-sw | |
| 8 | Arrow e-w | |
| 9 | Arrow n-s | |
| 10 | Arrow - all ways | |
| 11 | (X) cannot do action | |
| 12 | Help (? symbol) |
This operation is only effective when the mouse is "captured" - basically after a mouse-down but before the corresponding mouse-up. Otherwise the cursor is likely to be promptly restored by MUSHclient's cursor management code, for example to an I-beam cursor if it moves over text, or to the designated cursor if it moves over miniwindow hotspots.
Tips for avoiding flicker
MUSHclient maintains all miniwindows in offscreen bitmaps, so you can draw to them any way you want to (for example, draw a wall and then punch holes in it for doors). This will not cause any visible flicker.
However, to avoid visible flicker, all drawing should be done in a single script call. Thus anything that cannot be done immediately should be cached until the window can be drawn in a single script call. For example:
Bad
Draw an inventory window by updating the miniwindow as each line of inventory arrives. This will cause flicker because the inventory will gradually "creep down" the window.
Good
Draw an inventory window by caching each line of inventory as it arrives. For example, in Lua you could use table.insert to add the inventory line to a table. Then when the inventory has completely arrived, simply traverse the table, drawing each item in quick succession, in a single script call.
Other pages about miniwindows
- Introduction
- Creating miniwindows
- Drawing shapes
- Drawing text
- Drawing images
- Hotspots
- Blending images