Skip to content

Easy DIY Miniwindows

Avi Kelman edited this page Oct 29, 2020 · 45 revisions

The Aardwolf MUSHclient Package now includes special Lua code modules to bypass most or all of the horrible complexity of making miniwindows for your plugins.

Instructions

First, your plugin must be written in Lua. If you don't like Lua, I'm sorry.

Add require "themed_miniwindows" at the top of your plugin's script section.

To make a basic miniwindow, call:

my_window = ThemedBasicWindow(
   id,                    -- string, required, a unique identifier for this window
   default_left_position, -- integer, required, where to put it if the player hasn't moved it
   default_top_position,  -- integer, required, where to put it if the player hasn't moved it
   default_width,         -- integer, required, how big to make it if the player hasn't moved it
   default_height,        -- integer, required, how big to make it if the player hasn't moved it
   title,                 -- string, optional (nil means no titlebar), text to put into the title
   title_alignment,       -- string, optional (default is "center"), "left", "center", or "right"
   is_temporary,          -- boolean, optional (default is false), true adds a close button in the top left
   resizer_type,          -- nil/integer, optional (default is nil), nil for non-resizeable, 1 for demi, 2 for full
   do_while_resizing,     -- function, optional (default is nil), display function to call while resizing
   do_after_resizing,     -- function, optional (default is nil), display function to call after resizing is done
   do_on_delete,          -- function, optional (default is nil), cleanup function to call when closed/deleted
   title_font_name,       -- string, optional (default is Dina), override the default font name
   title_font_size        -- integer, optional (default is 10), override the default font size
)

Then draw whatever you want within the bounds of my_window.bodyleft, my_window.bodytop, my_window.bodyright, and my_window.bodybottom using the standard miniwindow drawing functions. There is no protection against you drawing on top of the window frame (titlebar, border, etc). You must protect yourself and stay within the lines. Get your magnifying glass out and make sure you don't accidentally draw over the edges.

Put all of your custom drawing code into one function and assign it as do_after_resizing and do_while_resizing above. If your drawing is too slow for smooth resizing, make a smaller faster function and assign that as do_while_resizing instead.

Drawing to miniwindows does not automatically update the screen, so after your custom drawing code is finished, you may want to do CallPlugin("abc1a0944ae4af7586ce88dc", "BufferedRepaint"). This code will handle it for you during resizing, but not at other times.

If you need to reapply the window dressing (e.g. maybe you want to paint content partially behind the resizer widget), call my_window:dress_window().

To delete my_window, call my_window:delete(). Creating a new easy miniwindow with the same unique identifier will replace the previous one, so if you're just re-creating an existing one, there's no need to call delete() on it first.

Easy miniwindows will remember their size and location automatically if the player moves them around or resizes them. To reset my_window to its default position and size, call my_window:reset().

To programmatically resize my_window without dragging the corner, call my_window:resize(width, height).

To show/hide my_window, call my_window:show() or my_window:hide().

To get my_window's special WindowMenu objects (it comes pre-made with a right-click menu with commands to move the window to the front/back), call my_window:get_menu_items(). It returns a string and a numerically-indexed table of functions. You are expected to always prefix your WindowMenu strings with "!" in order to use the numeric indexes. If you want to override the hotspot that creates the right-click menu, you can optionally use these to migrate the built-in menu options into your own custom menu. If you don't know what this means or are confused, feel free to ask Fiendish in-game.

To change Z-order (front/back placement) of my_window without using the right-click menu, call my_window:bring_to_front() or my_window:send_to_back().

To make a text miniwindow, call:

my_window = ThemedTextWindow(
   id,                    -- string, required, a unique identifier for this window
   default_left_position, -- integer, required, where to put it if the player hasn't moved it
   default_top_position,  -- integer, required, where to put it if the player hasn't moved it
   default_width,         -- integer, required, how big to make it if the player hasn't moved it
   default_height,        -- integer, required, how big to make it if the player hasn't moved it
   title,                 -- string, optional (nil means no titlebar), text to put into the title
   title_alignment,       -- string, optional (default is "center"), "left", "center", or "right"
   is_temporary,          -- boolean, optional (default is false), true adds a close button in the top left
   resizeable,            -- boolean, optional (default is false), make the window resizeable
   text_scrollable,       -- boolean, optional (default is false), add a scrollbar and mousewheel scrolling
   text_selectable,       -- boolean, optional (default is false), make the text selectable
   text_copyable,         -- boolean, optional (default is false), make the text copyable via right-click
   url_hyperlinks,        -- boolean, optional (default is false), turn detected URLs into clickable links
   autowrap,              -- boolean, optional (default is false), automatically wrap text lines that are too wide
   title_font_name,       -- string, optional (default is Dina), override the title font name
   title_font_size,       -- integer, optional (default is 10), override the title font size
   text_font_name,        -- string, optional (default is Dina), override the body text font name
   text_font_size,        -- integer, optional (default is 10), override the body text font size
   text_max_lines,        -- integer, optional (default is 1000), maximum number of text lines to keep
   text_padding           -- integer, optional (default is 5 pixels), space between text and miniwindow frame
)

In addition to all of the functions from ThemedBasicWindow, ThemedTextWindow also has:

To add a text string with Aardwolf color codes embedded or to add runs of MUSHclient styles, call my_window:add_text(string_or_styles). This also accepts multiple lines at once either by embedding "\n" in your text string or nesting multiple stylerun tables in an enclosing table. (There are demos of this below.)

To clear the text contents, call my_window:clear().

To add clickable 3D buttons, call

my_window:add_3d_text_button(
   id,                 -- string, required, a unique identifier for this button
   left,               -- integer, optional (default is my_window.bodyleft), where to put it in the window
   top,                -- integer, optional (default is my_window.bodytop), where to put it in the window
   text,               -- string, optional (default is nothing), what to write on the button
   utf8,               -- boolean, optional (default is false), whether the text should be interpreted as utf8
   tooltip,            -- string, optional (default is none), mouseover tooltip
   mousedown_callback, -- function, optional (default is none), function to call when the button is pressed down
   mouseup_callback,   -- function, optional (default is none), function to call when the pressed button is released
   font,               -- string, optional (default is my_win.title_font), which font to use
   x_padding,          -- integer, optional, how much space between the button text and the edge of the button
   y_padding           -- integer, optional, how much space between the button text and the edge of the button
)

Demos

require "themed_miniwindows"
my_window = ThemedBasicWindow("testwindow", 100, 100, 200, 150, "Hello", "center", true, 1)

Screenshot of miniwindow demo


You can have colorized window titles with multiple lines (use $C to set color back to the theme default).

require "themed_miniwindows"
my_window = ThemedBasicWindow(
   "testwindow", 100, 100, 200, 150, "He@x123llo\n@GHe$Cllo", "center", true, 1
)

Screenshot of miniwindow demo


Titles can also be one or more lines of styles.

require "themed_miniwindows"
title_styles = {
   {
      {
         bold=false,
         backcolour=0,
         length=11,
         textcolour=12632256,
         text="Hello"
      }
   },{
      {
         bold=true,
         backcolour=0,
         length=10,
         textcolour=255,
         text="Hello"
      }
   }
}
my_window = ThemedBasicWindow("testwindow", 100, 100, 200, 150, title_styles, "center", true, 1)

Screenshot of miniwindow demo


Alternate resizer style.

require "themed_miniwindows"
my_window = ThemedBasicWindow("testwindow", 100, 100, 200, 150, "Hello", "left", false, 2)

This is just a demo. Don't actually use resizer type 2 without a scrollbar. It's ugly.

Screenshot of miniwindow demo


require "themed_miniwindows"
my_window = ThemedTextWindow("testwindow", 200, 200, 200, 200, "Hello Hello", "center", false, true, false)
for i=1,10 do
   my_window:add_color_line(tostring(i).."@WFoo@RFoo@MFoo@CFoo")
end

Screenshot of miniwindow demo


require "themed_miniwindows"
my_window = ThemedTextWindow("testwindow", 200, 200, 200, 200, "Hello Hello", "center", false, true, true)
for i=1,100 do
   my_window:add_color_line(tostring(i).."@WFoo@RFoo@MFoo@CFoo")
end

Screenshot of miniwindow demo


require "themed_miniwindows"
my_window = ThemedBasicWindow("testwindow", 100, 100, 200, 150, "Hello", "center", true, 1)
my_window:add_3d_text_button(
   "testbutton",
   my_window.bodyleft + 20,
   my_window.bodytop + 20,
   "BUTTON GO ZOOM",
   false,
   nil,
   function(flags, button_id) print("CLICKED", button_id) end,
   function(flags, button_id) print("RELEASED", button_id) end,
   nil,
   5,
   5
)

Screenshot of miniwindow demo

Clicking the button prints:

CLICKED testbutton

RELEASED testbutton


require "themed_miniwindows"
my_window = ThemedTextWindow("testwindow", 200, 200, 200, 200, "Hello Hello", "center", false, true, true)
for i=1,100 do
   my_window:add_text("1234567890\n@R0987654321")  -- \n means new line
end

or

require "themed_miniwindows"
my_window = ThemedTextWindow("testwindow", 200, 200, 200, 200, "Hello Hello", "center", false, true, true)
styles = {                    -- begin multiple lines
   {                          -- begin line
      {                       -- begin style in line
         bold=false,
         backcolour=0,
         length=11,
         textcolour=12632256,
         text="1234567890"
      }                       -- end style in line
   },{                        -- end line, begin new line
      {                       -- begin style in line
         bold=true,
         backcolour=0,
         length=10,
         textcolour=255,
         text="0987654321"
      }                       -- end style in line
   }                          -- end line
}                             -- end multiple lines
for i=1,100 do
   my_window:add_text(styles)
end

Screenshot of miniwindow demo

Clone this wiki locally