[Home] [Downloads] [Search] [Help/forum]

Miniwindows in MUSHclient - Drawing shapes

Written by Nick Gammon - July 2008. Updated September 2010.

On this page:

See also:

Examples on this page

Most of the examples on this page are drawn in a 100 x 100 pixel window, with a grid drawn every 20 pixels to make it clearer the effect of the example code. The code for producing the grid is described in Creating miniwindows.

Pen parameters

Many functions below use a "pen". This is something used to draw lines. To save explaining the pen parameters for every function they are listed here:

For a particular shape, specify style 5 (miniwin.pen_null) if you only want to fill the shape, and not stroke it as well.


Brush parameters

Many functions below use a "brush". This is something used to fill the interior of a shape. To save explaining the brush parameters for every function they are listed here:


Rectangle coordinates

In many functions described below you specify the rectangle in which the shapes is to appear (including ellipses, circles, etc.). As a shorthand you can specify a negative number, or zero, for the bottom or right side. This is taken to be offset from the bottom or right edge of the containing miniwindow. For example:


Straight lines

WindowLine function prototype:

This draws a line from x1,y1 to x2,y2 with the designated pen.

Example of drawing a line


Arcs

WindowArc function prototype:

This draws an arc from x1,y1 to x2,y2 inside the box (Left,Top,Right,Bottom) with the designated pen.

Example of drawing an arc

The example above shows the enclosing rectangle, in blue, and the starting and ending points, in red, to illustrate how the arc works. They are not drawn as part of the arc, but shown to illustrate the idea.


Polygons

WindowPolygon function prototype:

This draws a polygon (series of straight lines) connecting the specified points, with the designated pen and filled with the designated brush.

Example of drawing a polygon


Rectangles

WindowRectOp function prototype:

This draws a rectangle in various styles, controlled by the Action parameter. You can also use WindowCircleOp with an action of 2 (miniwin.circle_rectangle) to draw rectangles with a pen and brush.

Examples of drawing rectangles

Resulting image is to the left of the corresponding code.

    
    -- frame
    WindowRectOp (win, miniwin.rect_frame, 20, 20, 70, 70, 
                  ColourNameToRGB("blue"))  -- outline
    
    
    -- fill
    WindowRectOp (win, miniwin.rect_fill, 50, 20, 80, 80, 
                  ColourNameToRGB("green"))  -- filled
    
    
    -- invert
    WindowRectOp (win, miniwin.rect_fill, 50, 20, 80, 80, 
                  ColourNameToRGB("green"))  -- draw rectangle
    WindowRectOp (win, miniwin.rect_invert, 5, 5, 90, 90, 0)   -- invert a larger one
    
    
    -- 3D style
    WindowRectOp (win, miniwin.rect_3d_rect, 50, 30, 70, 70, 
                  ColourNameToRGB("springgreen"), ColourNameToRGB("green"))
    
    
    -- 3D edge
    WindowRectOp (win, miniwin.rect_draw_edge, 30, 30, 70, 70, 
                  miniwin.rect_edge_raised, 
                  miniwin.rect_edge_at_all)  -- raised, not filled
    
    
    -- 3D edge, raised, filled
    WindowRectOp (win, miniwin.rect_draw_edge, 30, 30, 70, 70, 
                  miniwin.rect_edge_raised, 
                  miniwin.rect_edge_at_all + 
                    miniwin.rect_option_fill_middle)  -- raised, filled
    
    
    -- 3D edge, raised, filled, soft
    WindowRectOp (win, miniwin.rect_draw_edge, 30, 30, 70, 70, 
                  miniwin.rect_edge_raised, 
                  miniwin.rect_edge_at_all + 
                    miniwin.rect_option_fill_middle + 
                    miniwin.rect_option_softer_buttons)  -- raised, filled, softer
    
    
    -- 3D edge, flat, filled
    WindowRectOp (win, miniwin.rect_draw_edge, 30, 30, 70, 70, 
                  miniwin.rect_edge_raised, 
                  miniwin.rect_edge_at_all + 
                    miniwin.rect_option_fill_middle + 
                    miniwin.rect_option_softer_buttons + 
                    miniwin.rect_option_flat_borders)  -- raised, filled, softer, flat
    
    
    -- 3D edge, etched, filled
    WindowRectOp (win, miniwin.rect_draw_edge, 30, 30, 70, 70, 
                  miniwin.rect_edge_etched, 
                    miniwin.rect_edge_at_all + miniwin.rect_option_fill_middle)  -- etched, filled
    

There are more things you can try with rectangles, such as "bump" and "sunken" styles.


Ellipses, Filled Rectangles, Round Rectangles, Chords, Pies

WindowCircleOp function prototype:

    long WindowCircleOp(BSTR Name, short Action, long Left, long Top, long Right, long Bottom, long PenColour, long PenStyle, long PenWidth, long BrushColour, long BrushStyle, long Extra1, long Extra2, long Extra3, long Extra4);

This draws an ellipse, rectangle, round rectangle, chord or pie, controlled by the Action parameter. Unlike WindowRectOp, described above, the rectangles drawn here can be filled with a brush, thus allowing you to have patterned interiors if desired.

If you just want to draw a plain rectangle, however, WindowRectOp may be easier to use.

  • Name - the name of an existing miniwindow. Names are case-sensitive.

  • Action - what sort of shape to draw, as follows:

    ValuePurposeLua symbol
    1 Ellipse miniwin.circle_ellipse
    2 Rectangle miniwin.circle_rectangle
    3 Round Rectangle miniwin.circle_round_rectangle
    4 Chord miniwin.circle_chord
    5 Pie miniwin.circle_pie

  • Left, Top, Right, Bottom - describes the rectangle into which the shape must fit.

  • PenColour, PenStyle, PenWidth - the pen colour, style, and width as described at the top of this page.

  • BrushColour, Brushstyle - the brush colour and style as described at the top of this page.

  • Extra1, Extra2, Extra3, Extra4 - used for some actions.

Examples of drawing ellipses and other shapes

Resulting image is to the left of the corresponding code.

    
    -- circle, ellipse
    WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                    0, 0, 40, 40,                -- Left, Top, Right, Bottom
                    ColourNameToRGB("blue"), miniwin.pen_solid, 2, -- pen width 2
                    ColourNameToRGB("cyan"), miniwin.brush_solid)  -- brush
    WindowCircleOp (win, miniwin.circle_ellipse,  -- ellipse
                    50, 20, 100, 100,             -- Left, Top, Right, Bottom
                    ColourNameToRGB("magenta"), miniwin.pen_solid, 2, -- pen width 2
                    ColourNameToRGB("cyan"), miniwin.brush_solid)     -- brush
    
    
    -- square, rectangle
    
    WindowCircleOp (win, miniwin.circle_rectangle, -- square
                    5, 5, 40, 40,                  -- Left, Top, Right, Bottom
                    ColourNameToRGB("blue"), miniwin.pen_solid, 3,      -- pen width 3
                    ColourNameToRGB("cyan"), miniwin.brush_fine_pattern)-- brush
    WindowCircleOp (win, miniwin.circle_rectangle, -- rectangle
                    50, 20, 95, 95,                -- Left, Top, Right, Bottom
                    ColourNameToRGB("magenta"), miniwin.pen_solid, 3,       -- pen width 3
                    ColourNameToRGB("cyan"), miniwin.brush_waves_horizontal)-- brush
    
    
    -- round rectangle
    WindowCircleOp (win, miniwin.circle_round_rectangle, -- round rectangle
                    15, 15, 90, 90,                      -- Left, Top, Right, Bottom
                    ColourNameToRGB("blue"), miniwin.pen_solid, 2,          -- pen width 2
                    ColourNameToRGB("cyan"), miniwin.brush_coarse_pattern,  -- brush
                    25,   -- width of the ellipse used to draw the rounded corner
                    25)   -- height of the ellipse used to draw the rounded corner
    
    
    -- chord
    WindowCircleOp (win, miniwin.circle_chord,  -- chord
                    15, 15, 90, 90,             -- Left, Top, Right, Bottom
                    ColourNameToRGB("green"), miniwin.pen_solid, 2, -- pen width 2
                    ColourNameToRGB("cyan"), miniwin.brush_solid,   -- brush
                    40, 10,   -- x, y position of the chord's starting point
                    70, 95)   -- x, y position of the chord's ending point
    

The example above shows the enclosing rectangle, in blue, and the starting and ending points, in red, to illustrate how the chord works. They are not drawn as part of the chord, but shown to illustrate the idea.

    
    -- pie
    WindowCircleOp (win, miniwin.circle_pie,    -- pie
            15, 15, 90, 90,                     -- Left, Top, Right, Bottom
            ColourNameToRGB("green"), miniwin.pen_solid, 2,  -- pen width 2
            ColourNameToRGB("cyan"), miniwin.brush_solid,    -- brush
            60, 10,     -- the x, y position of the pie's starting point
            80, 80)     -- the x, y position of the pie's ending point
    

The example above shows the enclosing rectangle, in blue, and the starting and ending points, in red, to illustrate how the pie works. They are not drawn as part of the pie, but shown to illustrate the idea.


Bézier curves

WindowBezier function prototype:

    long WindowBezier(BSTR Name, BSTR Points, long PenColour, long PenStyle, long PenWidth);

Draws one or more Bézier splines. This function draws cubic Bézier splines by using the endpoints and control points specified by the Points parameter. The first spline is drawn from the first point to the fourth point by using the second and third points as control points. Each subsequent spline in the sequence needs exactly three more points: the end point of the previous spline is used as the starting point, the next two points in the sequence are control points, and the third is the end point.

  • Name - the name of an existing miniwindow. Names are case-sensitive.

  • Points - a string consisting of pairs of numbers, one for each point, in the format x1,y1,x2,y2 ...

    For example: "20,50,180,50" would specify two points, one at 20,50 and one at 180,50.

    You must have at least 4 points (the start, and 3 points per spline), which is 8 numbers. The number of numbers in the string must be even (divisible by two), as it takes a pair of numbers to specify one point. Also, since you need 3 points per spline, the number of numbers in the Points string must have a remainder of 2 when divided by 6 (3 points per spline, plus the start point).

  • PenColour, PenStyle, PenWidth - the pen colour, style, and width as described at the top of this page.

Example of drawing a Bézier curve

    
     WindowBezier (win, "30, 20, 5, 90, 50, 90, 80, 30", 
                  ColourNameToRGB("blue"), miniwin.pen_solid, 2)  -- pen
    

The example above shows the control points, in red, to illustrate how the Bézier curve works. They are not drawn as part of the curve, but shown to illustrate the idea.


Gradients

WindowGradient function prototype:

    long WindowGradient(BSTR Name, long Left, long Top, long Right, long Bottom, long StartColour, long EndColour, short Mode);

Draws a gradient - that is a rectangle that gradually changes from the start colour to the end colour.

  • Name - the name of an existing miniwindow. Names are case-sensitive.

  • Left, Top, Right, Bottom - describes the rectangle to draw the gradient into.

  • StartColour - the colour to start the gradient. For mode 3 (miniwin.gradient_texture) the StartColour has 3 components, red multiplier, green multiplier, blue multiplier. These are multiplied by the generated colour to give special effects to the generated texture. For example: 0x010203 would multiply the blue component by 1, the green component by 2 and the red component by 3. You can use ColourNameToRGB to convert a colour name (like "red" or "green") into a colour number.

  • EndColour - the colour to end the gradient. You can use ColourNameToRGB to convert a colour name (like "red" or "green") into a colour number.

  • Mode - the drawing direction. One of:

    ValuePurposeLua symbol
    1 Horizontal - left to right miniwin.gradient_horizontal
    2 Vertical - top to bottom miniwin.gradient_vertical
    3 Texture - XOR pattern miniwin.gradient_texture

Examples of drawing a gradient

    
    WindowGradient (win, 20, 110, 160, 180, 
                    ColourNameToRGB ("red"), 
                    ColourNameToRGB ("yellow"), 
                    miniwin.gradient_horizontal)  -- left to right
    
    WindowGradient (win, 20, 20, 160, 100, 
                    ColourNameToRGB ("dodgerblue"), 
                    ColourNameToRGB ("lightsalmon"), 
                    miniwin.gradient_vertical)  -- top to bottom
    
    

    
    WindowGradient (win, 0, 00, 256, 256, 
                    0x010201, 
                    0,
                    miniwin.gradient_texture)  -- texture
                    
    


Setting pixels

WindowSetPixel function prototype:

    long WindowSetPixel(BSTR Name, long x, long y, long Colour);

Sets a single pixel in the miniwindow.

  • Name - the name of an existing miniwindow. Names are case-sensitive.

  • x, y - the location of the pixel

  • Colour - the colour to set the pixel to. Note that the pixel which appears in the window may not necessarily be the exact one you chose, depending on the colour depth of your monitor. You can use ColourNameToRGB to convert a colour name (like "red" or "green") into a colour number.

Warning - although setting individual pixels is reasonably fast, if you need to set a lot (for example, to draw a line or a box), it would be much faster to use the appropriate dedicated function (such as WindowLine). This is because to draw boxes and lines, especially large ones, or filled ones, would take many, many calls to WindowSetPixel to achieve the same result.

Example of setting pixels

    
    for x = 1, 360 do
      local y = math.sin (math.rad (x)) * 100
      WindowSetPixel (win, x, y + 120, 0xFF0000)
    end -- for 
    
    

You can also use WindowGetPixel to get the RGB colour code at a particular pixel location.


Other pages about miniwindows


[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]