1679 lines
74 KiB
Lua
1679 lines
74 KiB
Lua
--[=[--
|
|
InfoBox.lua version 1.2
|
|
Encapsulates and enhances Infobar functionality into miniwindows; gauges and status text.
|
|
14-DEc-08
|
|
|
|
by: WillFa (Spellbound on 3k.org:3000)
|
|
portions borrowed or adapted from samples by Nick Gammon.
|
|
|
|
License: Free for public use in your MushClient plugins and scripts as long as credit for this module is
|
|
attributed to WillFa, and Nick Gammon.
|
|
|
|
Assumes that the Sylfaen font is installed on the system. Change line 67 if it is not.
|
|
|
|
Requires: MushClient v. 4.37+ for complete functionality. (CloseWindow() uses DeleteWindow MC function.)
|
|
MushClient v. 4.35+ for basic functionality. (WindowGradient calls)
|
|
|
|
Usage:
|
|
require "InfoBox"
|
|
MW = InfoBox:New()
|
|
MW:AddBar("text", percent, "green", "red")
|
|
MW:Update()
|
|
|
|
Tutorial Demo can be found in the included InfoBox_Demo.xml plugin.
|
|
|
|
Reference help for functions and values you will actually use can be obtained from the Doc() function.
|
|
i.e.:
|
|
InfoBox:Doc()
|
|
InfoBox:Doc("AddBar")
|
|
|
|
|
|
General Usage is more easily deduced by tprint(InfoBox), tprint(MW), tprint(MW.Bar) rather than reading this source.
|
|
The metatables are setup in such a way that tprint will not recurse up the inheritance chain and spam you.
|
|
--]=]--
|
|
|
|
local world, colour_names = world, colour_names, _M
|
|
local os = {time = os.time}
|
|
local math, string, table, bit = math, string, table, bit
|
|
local tonumber, tostring, rawget, rawset, type, print = tonumber, tostring, rawget, rawset, type, print
|
|
local unpack, assert, require, getmetatable, setmetatable = unpack, assert, require, getmetatable, setmetatable
|
|
local pairs, ipairs, check = pairs, ipairs, check
|
|
local Global = _G
|
|
local capitalize, CalcShades, SplitRGB, idx, newidx
|
|
local CalcWindowHeight, strip_colours, sidewindows, Draw, DoFade, PrintText, ResizeOutput
|
|
local fontProps = {"fontID", "fontName", "fontSize", "fontBold", "fontItalic", "fontUnderline", "fontStrikeout", "fontCharset", "fontPitchAndFamily"}
|
|
local commas, CheckStyle, DoFade, PrintText
|
|
local matteHilight, matteShadow, Bar, ansiCodes, ansiColors, _Doc
|
|
|
|
module(...)
|
|
|
|
setmetatable ( _M, {__index = world, class = "module"}) -- find all the MushClient Functions
|
|
|
|
windowWidth = 240
|
|
windowHeight = 7 -- this will change as more bars are added. It gives 5 pixels padding top and bottom.
|
|
|
|
columns = 0
|
|
rows = 0
|
|
axis = "rows"
|
|
|
|
backgroundColour = 0x808080
|
|
matteHilight = 0xb2b2b2
|
|
matteShadow = 0x4e4e4e
|
|
|
|
windowPosition = 7
|
|
windowFlags = 0
|
|
|
|
fontID = "fn"
|
|
fontName = "Sylfaen"
|
|
fontSize = 10
|
|
fontPadding = 2
|
|
fontBold = true
|
|
fontItalic = false
|
|
fontUnderline = false
|
|
fontStrikeout = false
|
|
fontCharset = 1
|
|
fontPitchAndFamily = 0
|
|
|
|
displaceOutput = false
|
|
|
|
ansiCodes = {"k", "r", "g", "y", "b", "m", "c", "w"}
|
|
ansiColors = {} -- Gets populated after capitalize() is defined.
|
|
customColourCodes = {}
|
|
|
|
-- Enumeration tables
|
|
|
|
textStyles = { plain = 0,
|
|
matte = 1,
|
|
raised = 2,
|
|
sunken = 4
|
|
}
|
|
|
|
barStyles = { textOnly = 0, -- Status line
|
|
sunken = 1, -- Frames
|
|
raised = 2,
|
|
raisedCap = 2^2, -- Caption is framed too.
|
|
flat = 2^3,
|
|
glass = 2^4,
|
|
solid = 2^5, -- Fills
|
|
gradientScale = 2^6, -- gradient midpoint is value/2. Fill shrinks
|
|
gradientFixed = 2^7, -- gradient midpoint is always threshold.
|
|
gradientShift = 2^8, -- Thermometer style; Fill remains 100%, gradient position shifts wth value
|
|
}
|
|
|
|
captionPlacements = { left = 0,
|
|
innerLeft = 1,
|
|
innerRight = 2,
|
|
right = 3,
|
|
center = 4,
|
|
centerCell = 5,
|
|
}
|
|
|
|
windowPositions = { NW = 4,
|
|
N = 5,
|
|
NE = 6,
|
|
E = 7,
|
|
SE = 8,
|
|
S = 9,
|
|
SW = 10,
|
|
W = 11,
|
|
}
|
|
|
|
-- End Enumerations
|
|
|
|
|
|
-- Bar Functions/Methods
|
|
Bar = { --Properties
|
|
textStyle = 0,
|
|
threshold = 30,
|
|
textColour = 0x222222 ,
|
|
"Caption", -- 1 = "Caption" see InsertBars() for the tricky code that this uses.
|
|
caption = "",
|
|
"Value", -- 2 = "Value" see InsertBars()
|
|
value = 0,
|
|
"GoodColour", -- 3 = ...
|
|
goodColour = 0x00DD00,
|
|
"BadColour", -- 4 = ...
|
|
badColour = 0x0000DD,
|
|
"AnchorRight", -- 5 = ...
|
|
anchorRight = false,
|
|
"BarStyle", -- 6 = ...
|
|
barStyle = 33,
|
|
gaugeLeft = 5 ,
|
|
captionPlacement = 1,
|
|
padding = 3,
|
|
cellPadding = 4,
|
|
|
|
--End Properties
|
|
}
|
|
setmetatable (Bar, {__index = _M, class = "bar"})
|
|
|
|
--[=[ Internal Function that writes captions ]=]--
|
|
function PrintText (self, vOffset, hOffset)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "PrintText", self.windowName, self.id))
|
|
local MatteText = strip_colours(self.caption)
|
|
local width = WindowTextWidth (self.parent.windowName, self.fontID, MatteText)
|
|
local side = 0
|
|
if self.matteHilight == nil then
|
|
self.matteHilight, self.matteShadow = self.backgroundColour,self.backgroundColour
|
|
for i = 1,10 do
|
|
self.matteHilight = AdjustColour(self.matteHilight,2)
|
|
self.matteShadow = AdjustColour(self.matteShadow,3)
|
|
end end
|
|
vOffset = vOffset + self.fontPadding
|
|
if self.captionPlacement == 0 then
|
|
side = hOffset + self.gaugeLeft - WindowTextWidth ( self.parent.windowName, self.fontID, MatteText) -2
|
|
elseif self.captionPlacement == 1 then
|
|
side = hOffset + self.gaugeLeft + 5
|
|
elseif self.captionPlacement == 2 then
|
|
side = hOffset + self.gaugeLeft + self.gaugeWidth - width - 5
|
|
elseif self.captionPlacement == 3 then
|
|
side = hOffset + self.gaugeLeft + self.gaugeWidth + 2
|
|
elseif self.captionPlacement == 4 then
|
|
side = hOffset + self.gaugeLeft + ( (self.gaugeWidth-WindowTextWidth ( self.parent.windowName, self.fontID, MatteText) )/2)
|
|
elseif self.captionPlacement == 5 then
|
|
side = math.floor(hOffset + (self.cellWidth-WindowTextWidth ( self.parent.windowName, self.fontID, MatteText) ) / 2)
|
|
end
|
|
if self.barStyle == 0 then
|
|
if self.captionPlacement > 3 then
|
|
side = hOffset + math.floor( (self.cellWidth-WindowTextWidth ( self.parent.windowName, self.fontID, MatteText) ) / 2)
|
|
elseif self.captionPlacement < 2 then
|
|
side = hOffset + 5
|
|
elseif self.captionPlacement > 1 then
|
|
side = hOffset + self.parent.cellWidth - width - 5
|
|
end end
|
|
if self.textStyle > 0 then
|
|
if (self.textStyle % 2) == 1 then -- Matted
|
|
WindowText (self.parent.windowName, self.fontID, MatteText, side +1 , vOffset -1, 0, 0, self.backgroundColour)
|
|
-- Upper Right Matte
|
|
WindowText (self.parent.windowName, self.fontID, MatteText, side -1 , vOffset +1, 0, 0, self.backgroundColour)
|
|
-- Lower Left Matte
|
|
if self.textStyle == self.textStyles.matte then -- Only Matted
|
|
WindowText (self.parent.windowName, self.fontID, MatteText, side -1 , vOffset -1, 0, 0, self.backgroundColour)
|
|
-- Top Left Matte
|
|
WindowText (self.parent.windowName, self.fontID, MatteText, side +1 , vOffset +1, 0, 0, self.backgroundColour)
|
|
-- Bottom Right Matte
|
|
end
|
|
end
|
|
if bit.band(self.textStyle, self.parent.textStyles.raised) == self.textStyles.raised then -- Raised
|
|
WindowText (self.parent.windowName, self.fontID, MatteText, side +1 , vOffset +1, 0, 0, self.matteShadow)
|
|
-- Bottom Left Shadow
|
|
WindowText (self.parent.windowName, self.fontID, MatteText, side -1 , vOffset -1, 0, 0, self.matteHilight )
|
|
-- Top Left hilight
|
|
end
|
|
if bit.band(self.textStyle, self.textStyles.sunken) == self.textStyles.sunken then -- Sunken
|
|
WindowText (self.parent.windowName, self.fontID, MatteText, side -1 , vOffset -1, 0, 0, self.matteShadow)
|
|
-- Top Left Shadow
|
|
WindowText (self.parent.windowName, self.fontID, MatteText, side +1 , vOffset +1, 0, 0, self.matteHilight)
|
|
-- Bottom Left Hilight
|
|
end end
|
|
if self.caption == MatteText then
|
|
WindowText (self.parent.windowName, self.fontID, self.caption, side , vOffset, side + width, vOffset + self.fontHeight, self.textColour) -- Text
|
|
else
|
|
ansiColors["~"] = self.textColour
|
|
local customColours = self.customColourCodes or {}
|
|
local Text = string.gsub (self.caption or "", "@@", "\0") -- change @@ to 0x00
|
|
if Text:sub (1, 1) ~= "@" then
|
|
Text = "@~" .. Text
|
|
end
|
|
for colour, text in Text:gmatch ("@([%a~])([^@]+)") do
|
|
text = text:gsub ("%z", "@") -- put any @ characters back
|
|
if #text > 0 then
|
|
side = side + WindowText (self.windowName, self.fontID, text, side, vOffset, hOffset + self.cellWidth, vOffset + self.fontHeight, customColours[colour] or ansiColors[colour] or ansiColors["~"])
|
|
end end end
|
|
return vOffset - self.fontPadding
|
|
end
|
|
|
|
--[=[ Internal Function that does bitmask checking ]=]--
|
|
function CheckStyle(self, style)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "CheckStyle", self.windowName, self.id))
|
|
if bit.band(self.barStyle, style) > 0 then
|
|
return true
|
|
else
|
|
return false
|
|
end end
|
|
|
|
--[=[ Internal Function that draws the pretty boxes ]=]--
|
|
function Draw (self, vOffset, hOffset)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "Draw", self.windowName, self.id))
|
|
self.cellTop, self.cellLeft = vOffset , hOffset
|
|
WindowRectOp (self.windowName , 2, self.cellLeft, self.cellTop - 1 , self.cellLeft + self.cellWidth , self.cellTop + self.cellHeight + self.padding - 2 , self.backgroundColour, nil)
|
|
local Percent = self.value or 0
|
|
local colour, fcolour
|
|
if Percent < self.threshold then
|
|
colour = self.badColour
|
|
elseif Percent > 100 then
|
|
Percent = 100
|
|
for i = 1,15 do
|
|
colour = AdjustColour(self.goodColour,4) -- 20% more luminence
|
|
end
|
|
else
|
|
colour = self.goodColour
|
|
end
|
|
if self.fade == true then
|
|
colour = DoFade(self)
|
|
fcolour = colour
|
|
end
|
|
local pixels = self.gaugeWidth * Percent / 100
|
|
if self.barStyle > 0 then
|
|
local bezel = {[true] = 10, [false] = 5}
|
|
local frameLeft = self.cellLeft + self.gaugeLeft
|
|
local frameTop = self.cellTop + self.cellHeight - self.gaugeHeight
|
|
local frameRight = self.cellLeft + self.gaugeLeft + self.gaugeWidth
|
|
local frameBottom = self.cellTop + self.cellHeight
|
|
local topX, topY, bottomX, bottomY = frameLeft + 2, frameTop + 2 , self.cellLeft + self.gaugeLeft + pixels, frameBottom - 2
|
|
local colorL, colorR = self.badColour, (fcolour or self.goodColour)
|
|
local ftopX, ftopY, fbottomX, fbottomY = bottomX + 1, frameTop, frameRight, frameBottom --fill region for fixed gradients
|
|
if self.anchorRight == true then
|
|
topX , topY = frameRight - pixels , frameTop + 2
|
|
bottomX, bottomY = frameRight - 2, frameBottom - 2
|
|
ftopX , ftopY = frameLeft , frameTop
|
|
fbottomX, fbottomY = frameRight - pixels - 2, frameBottom
|
|
colorL, colorR = (fcolour or self.goodColour), self.badColour
|
|
end
|
|
if bit.band(barStyles.raisedCap, self.barStyle) == barStyles.raisedCap then
|
|
if self.captionPlacement == 0 then
|
|
frameLeft = self.cellLeft + 3
|
|
elseif self.captionPlacement == 3 then
|
|
frameRight = self.cellLeft + self.cellWidth -3
|
|
end end
|
|
if Percent >= 1 then
|
|
if CheckStyle(self, self.barStyles.solid) then
|
|
check (WindowRectOp (self.parent.windowName, 2, topX , topY , bottomX , bottomY , colour) )
|
|
elseif CheckStyle(self, self.barStyles.gradientScale) then -- scaled gradient fills
|
|
check (WindowGradient (self.parent.windowName, topX, topY, bottomX, bottomY, colorL, colorR, 1 ) )
|
|
elseif CheckStyle(self, self.barStyles.gradientFixed) then -- fixed gradients.
|
|
local padWidth, padFillColour = self.gaugeWidth * ( (math.abs(50-self.threshold) *2)/100), (fcolour or self.goodColour)
|
|
if self.threshold > 50 then
|
|
padFillColour = self.badColour
|
|
end
|
|
check (WindowRectOp (self.parent.windowName, 2, topX , topY , bottomX, bottomY, padFillColour) )
|
|
if ( (self.anchorRight == false) and (self.threshold <= 50) ) or
|
|
( (self.anchorRight == true) and (self.threshold > 50) ) then --need more colorR than colorL
|
|
check (WindowGradient (self.parent.windowName, self.cellLeft + self.gaugeLeft, frameTop, frameRight - padWidth, bottomY, colorL, colorR, 1 ) )
|
|
elseif ( (self.anchorRight == true) and (self.threshold <= 50) ) or
|
|
( (self.anchorRight == false) and (self.threshold > 50) ) then --need more colorL than colorR
|
|
check (WindowGradient (self.parent.windowName, self.cellLeft + self.gaugeLeft + padWidth, topY, frameRight -2, bottomY, colorL, colorR, 1 ) )
|
|
end
|
|
check (WindowRectOp (self.parent.windowName, 2, ftopX , ftopY , fbottomX , fbottomY -1 , self.backgroundColour) )
|
|
elseif CheckStyle(self, self.barStyles.gradientShift) then -- Thermometer gradients.
|
|
local midpointX = bottomX
|
|
local pixel = self.gaugeWidth / 100
|
|
local gradientWidth = math.min(30, (100 - self.value) * pixel, self.value * pixel)
|
|
if self.anchorRight == true then
|
|
colorL, colorR = (fcolour or self.goodColour), self.badColour
|
|
midpointX = topX
|
|
end
|
|
check (WindowRectOp (self.parent.windowName, 2, topX , topY , bottomX , bottomY, (fcolour or self.goodColour) ) )
|
|
check (WindowRectOp (self.parent.windowName, 2, ftopX, ftopY , fbottomX, bottomY, self.badColour) )
|
|
check (WindowGradient (self.parent.windowName, midpointX - gradientWidth, topY, midpointX + gradientWidth, bottomY, colorR, colorL, 1 ) )
|
|
check (WindowRectOp (self.parent.windowName, 2, self.cellLeft + 1, self.cellTop, self.cellLeft + self.gaugeLeft, self.cellTop + self.cellHeight , self.backgroundColour) )
|
|
check (WindowRectOp (self.parent.windowName, 2, frameRight, frameTop, -2, frameBottom, self.backgroundColour) )
|
|
end
|
|
if CheckStyle(self, self.barStyles.glass) then -- glass frame
|
|
local glassWidth, dtX,dtY, dbX, dbY = pixels, topX, topY, bottomX, bottomY
|
|
if CheckStyle(self, self.barStyles.gradientShift) then
|
|
glassWidth = self.gaugeWidth
|
|
dtX, dtY, dbX, dbY = frameLeft + 2, frameTop + 1, frameRight - 2, frameBottom -1
|
|
end
|
|
check (WindowCreate ( self.parent.windowName .. "glass", 0,0, glassWidth, self.cellHeight - 2, 7, 0, 0x171717) )
|
|
check (WindowGradient(self.parent.windowName .. "glass", 0,0, 0, self.cellHeight * .50, 0x606060, 0xaaaaaa, 2) )
|
|
check (WindowGradient(self.parent.windowName .. "glass", 0,self.cellHeight * .51, 0, self.cellHeight -2, 0x7c7c7c, 0x393939, 2) )
|
|
check (WindowImageFromWindow ( self.parent.windowName, self.parent.windowName .. "glass", self.parent.windowName .. "glass") )
|
|
check (WindowBlendImage ( self.parent.windowName, self.parent.windowName .. "glass", dtX, dtY, dbX, dbY, 21, .45) )
|
|
elseif CheckStyle(self, barStyles.raised + barStyles.raisedCap + barStyles.sunken) then -- 3D frame rectangle
|
|
check (WindowRectOp (self.parent.windowName, 5, topX , topY , bottomX, bottomY, bezel[not CheckStyle(self, barStyles.sunken + barStyles.glass)] ,0x100F) )
|
|
end end
|
|
if bit.band( self.barStyle , 31 ) ~= 0 then -- frame rectangle on border
|
|
local pen = {[true]=1,[false]=5}
|
|
check (WindowRectOp (self.parent.windowName, pen[CheckStyle(self, self.barStyles.flat)], frameLeft, frameTop, frameRight, frameBottom, bezel[not CheckStyle(self, barStyles.raised + barStyles.raisedCap)], 15+0x1000) )
|
|
end end
|
|
PrintText (self, self.cellTop, self.cellLeft)
|
|
if type(self.button) == 'table' then
|
|
WindowAddHotspot(self.windowName, self.id, self.cellLeft, self.cellTop, self.cellLeft + self.cellWidth, self.cellTop + self.cellHeight,
|
|
self.button.mouseOver or "", self.button.cancelMouseOver or "", self.button.mouseDown or "", self.button.cancelMouseDown or "",
|
|
self.button.mouseUp or "", self.button.tooltipText or "", self.button.cursor or 0, 0 )
|
|
|
|
end
|
|
return self.cellTop + self.cellHeight + self.padding
|
|
end
|
|
|
|
--[=[ Internal Function that calculates different shades of colors ]=]--
|
|
function DoFade(self)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "DoFade", self.windowName, self.id))
|
|
local color
|
|
if self.shades == nil or (self.Bar.shades and self.goodColour ~= self.Bar.goodColour and self.badColour ~= self.Bar.badColour) then
|
|
self.shades = CalcShades(self, math.ceil(100 - self.threshold)/5)
|
|
end
|
|
if self.value >= self.threshold then
|
|
color = self.shades[math.ceil( (101-self.value)/5 )] or self.shades[#self.shades]
|
|
else
|
|
color = self.badColour
|
|
end
|
|
return color
|
|
end
|
|
|
|
|
|
--[=[ See :Doc( "Fade" ) --]=]--
|
|
function Bar:Fade (bool)
|
|
assert(bool and type(bool)=="boolean", "Boolean expected. Got " .. tostring( bool ) .. "(" .. type(bool) .. ")")
|
|
self.fade = bool
|
|
self.shades = nil
|
|
if bool then
|
|
DoFade(self)
|
|
end
|
|
end
|
|
|
|
|
|
--[=[ See :Doc( "TextColour" ) --]=]--
|
|
function Bar:TextColour (x)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "TextColour", self.windowName, self.id))
|
|
local n = tonumber(x) or tonumber(x,16) or ColourNameToRGB(x)
|
|
assert(n and n~= -1,'Bad value passed. Acceptable examples: "red", 255, 0x0000ff, "#FF0000" - Got '.. tostring(x) .. '('.. type(x) ..')')
|
|
self.textColour = n
|
|
end
|
|
|
|
--[=[ See :Doc( "ColourText" ) --]=]--
|
|
function Bar:ColourText(val, thresh, good, bad, neut)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "ColourText", self.windowName, self.id))
|
|
local n = tonumber(thresh)
|
|
if n then
|
|
if val == thresh then
|
|
self:TextColour(neut or good)
|
|
elseif val < thresh then
|
|
self:TextColour(bad)
|
|
else
|
|
self:TextColour(good)
|
|
end end end
|
|
|
|
--[=[ See :Doc( "GoodColour" ) --]=]--
|
|
function Bar:GoodColour (x)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "GoodColour", self.windowName, self.id))
|
|
local n = tonumber(x) or ColourNameToRGB(x)
|
|
assert(n and n~= -1,'Bad value passed. Acceptable examples: "red", 255, 0x0000ff, "#FF0000" - Got '.. tostring(x) .. '('.. type(x) ..')')
|
|
self.goodColour = n
|
|
self.shades = nil
|
|
end
|
|
|
|
--[=[ See :Doc( "BadColour" ) --]=]--
|
|
function Bar:BadColour (x)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "BadColour", self.windowName, self.id))
|
|
local n = tonumber(x) or ColourNameToRGB(x)
|
|
assert(n and n~= -1,'Bad value passed. Acceptable examples: "red", 255, 0x0000ff, "#FF0000" - Got '.. tostring(x) .. '('.. type(x) ..')')
|
|
self.badColour = n
|
|
self.shades = nil
|
|
end
|
|
|
|
--[=[ See :Doc( "AnchorRight" ) --]=]--
|
|
function Bar:AnchorRight (bool)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "AnchorRight", self.windowName, self.id))
|
|
if type(bool) == "boolean" then
|
|
bool = bool
|
|
else
|
|
bool = false
|
|
end
|
|
self.anchorRight = bool
|
|
if bool == false then
|
|
self.captionPlacement = 1
|
|
else
|
|
self.captionPlacement = 2
|
|
end end
|
|
|
|
--[=[ See :Doc( "Value" ) --]=]--
|
|
function Bar:Value (val)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "Value", self.windowName, self.id))
|
|
self.value = tonumber(val) or self.value
|
|
self.watchValue = nil
|
|
end
|
|
|
|
--[=[ See :Doc( "Caption" ) --]=]--
|
|
function Bar:Caption (txt)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "Caption", self.windowName, self.id))
|
|
self.watchCaption = nil
|
|
if tonumber(txt) then
|
|
self.caption = commas(txt)
|
|
elseif txt == nil then
|
|
self.caption = ""
|
|
else
|
|
self.caption = txt
|
|
end
|
|
end
|
|
|
|
--[=[ See :Doc( "TextStyle" ) --]=]--
|
|
function Bar:TextStyle (x)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "TextStyle", self.windowName, self.id))
|
|
self.textStyle = tonumber(x) or 1
|
|
end
|
|
|
|
--[=[ See :Doc( "Threshold" ) --]=]--
|
|
function Bar:Threshold (x)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "Threshold", self.windowName, self.id))
|
|
self.threshold = tonumber(x) or 30
|
|
self.shades = nil
|
|
end
|
|
|
|
--[=[ See :Doc( "BarStyle" ) --]=]--
|
|
function Bar:BarStyle (x)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "BarStyle", self.windowName, self.id))
|
|
assert ( tonumber(x) and tonumber(x) >= 0, "Invalid barstyle.")
|
|
self.barStyle = tonumber(x)
|
|
end
|
|
|
|
--[=[ See :Doc( "Padding" ) --]=]--
|
|
function Bar:Padding (x)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "Padding", self.windowName, self.id))
|
|
assert( tonumber(x), "Number of pixels needed. Got " .. type(x) )
|
|
local MiniWindow = self.parent or self
|
|
self.padding = tonumber(x)
|
|
MiniWindow:Resize()
|
|
end
|
|
|
|
--[=[ See :Doc( "WatchValue" ) --]=]--
|
|
function Bar:WatchValue (varName)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "WatchValue", self.windowName, self.id))
|
|
self.value = nil
|
|
self.watchValue = varName
|
|
end
|
|
|
|
--[=[ See :Doc( "WatchCaption" ) --]=]--
|
|
function Bar:WatchCaption (varName)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "WatchCaption", self.windowName, self.id))
|
|
self.caption = nil
|
|
self.watchCaption = varName
|
|
end
|
|
|
|
--[=[ Internal Function that hides in metatables ]=]--
|
|
local function idx (self, k)
|
|
local varName, val = rawget (self, "watch" .. capitalize(k) ) or ""
|
|
if (k == "value" or k == "caption" ) then
|
|
for z in varName:gmatch("([^%.%[%]]+)") do
|
|
local parent = val or Global
|
|
z = tonumber(z) or z
|
|
val = parent[z]
|
|
end
|
|
return val
|
|
else
|
|
local Parent = getmetatable(self)["parent"] --parent is hidden in a metatable so it doesn't tprint. Hooray for aesthetically pleasing wastes of processor cycles.
|
|
val = rawget (self, k)
|
|
val = val or Parent[k]
|
|
return val
|
|
end end
|
|
|
|
--[=[ Internal Function that hides in metatables ]=]--
|
|
local function newidx (self, k, v)
|
|
if (k == "value" and rawget (self,watchValue) ) or (k == "caption" and rawget (self, watchCaption) ) then
|
|
self["watch" .. capitalize(k)] = nil
|
|
end
|
|
rawset(self, k, v)
|
|
end
|
|
|
|
|
|
-- End Bar Functions
|
|
|
|
|
|
-- Global Functions
|
|
|
|
--[=[ See :Doc( "New" ) --]=]--
|
|
function _M:New (winName)
|
|
--TraceOut (string.format("%s: Window %s", "New", winName))
|
|
local mt = {
|
|
__index =
|
|
function (self, key)
|
|
if key == "cellWidth" then
|
|
return self.windowWidth / self.columns
|
|
elseif key == "gaugeWidth" then
|
|
return self.cellWidth - 10
|
|
else
|
|
return _M[key]
|
|
end end ,
|
|
__metatable = {class = "Box"}; }
|
|
local q = {}
|
|
setmetatable(q,mt) -- Window table inherits the module
|
|
q.Bars = {}
|
|
q.Bar = {}
|
|
for k,v in pairs(Bar) do q.Bar[k] = v end -- a separate instance of Bar so that...
|
|
setmetatable(q.Bar, {parent = q, class = "Bar", __index=
|
|
function (self, key)
|
|
local mt = getmetatable(self)
|
|
if key =="parent" then
|
|
return mt.parent
|
|
else
|
|
return mt.parent[key]
|
|
end end ,
|
|
}) -- Bar table instance inherits it's MiniWindow table instance
|
|
q.windowName = winName or CreateGUID() -- Will create a guid if none passed in. Fine for plugin use.
|
|
check (WindowCreate (q.windowName, 0, 0, 1, 1, q.windowPosition, q.windowFlags, q.backgroundColour) )
|
|
check (WindowFont (q.windowName, q.fontID, q.fontName, q.fontSize, q.fontBold, q.fontItalic, q.fontUnderline, q.fontStrikeout, q.fontCharset, q.fontPitchAndFamily) )
|
|
q.fontHeight = WindowFontInfo (q.windowName, q.fontID, 1) -- Default font height
|
|
q.Bar.cellHeight = q.fontHeight + q.Bar.cellPadding
|
|
q.Bar.gaugeHeight = q.Bar.cellHeight -- Default size of bars.
|
|
return q
|
|
end
|
|
|
|
--[=[ See :Doc( "BackgroundColour" ) --]=]--
|
|
function _M:BackgroundColour (col)
|
|
assert (col, "Nil passed. specify a colour.")
|
|
local n = tonumber(col) or ColourNameToRGB(col)
|
|
assert(n and n~= -1,'Bad value passed. Acceptable examples: "red", 255, 0x0000ff, "#FF0000" - Got '.. tostring(x) .. '('.. type(x) ..')')
|
|
self.backgroundColour = n
|
|
self.matteHilight, self.matteShadow = self.backgroundColour,self.backgroundColour
|
|
for i = 1,10 do
|
|
self.matteHilight = AdjustColour(self.matteHilight,2)
|
|
self.matteShadow = AdjustColour(self.matteShadow,3)
|
|
end
|
|
end
|
|
|
|
--[=[ See :Doc( "Rows" ) --]=]--
|
|
function _M:Rows(num)
|
|
assert(type(num)=="number" and num > 0, "How many rows? Need a positive number. Got " .. type(num) )
|
|
assert(self.parent == nil, "Pass a MiniWindow")
|
|
self.rows = num
|
|
self:Resize()
|
|
end
|
|
|
|
--[=[ See :Doc( "Columns" ) --]=]--
|
|
function _M:Columns(num)
|
|
assert(type(num)=="number" and num > 0, "How many columns? Need a positive number. Got " .. type(num) )
|
|
assert(self.parent == nil, "Pass a MiniWindow")
|
|
self.rows = math.ceil(#self.Bars/num)
|
|
self.columns = num
|
|
self:Resize()
|
|
end
|
|
|
|
--[=[ See :Doc( "AddBar" ) --]=]--
|
|
function _M:AddBar(...)
|
|
--TraceOut (string.format("%s: Window %s", "AddBar", self.windowName))
|
|
return self:InsertBar(#self.Bars + 1, ...)
|
|
end
|
|
|
|
--[=[ See :Doc( "InsertBar" ) --]=]--
|
|
function _M:InsertBar(index, ...)
|
|
--TraceOut (string.format("%s: Window %s Bar %i", "InsertBar", self.windowName, index))
|
|
assert(self ~= _M , "Pass a table created from ".. _NAME .. ":New(), not ".. _NAME .. " itself.")
|
|
assert(self.parent == nil, "Attempt to add a Bar to a Bar. Use table from ".. _NAME .. ":New() instead.")
|
|
assert(index, "Bars index must be passed.")
|
|
local MiniWindow = self.parent or self
|
|
--[[-- Expected possible values:
|
|
1= Caption,
|
|
2= Value,
|
|
3= GoodColor,
|
|
4= BadColor,
|
|
5= AnchoredRight, (whether the 0 value is on the left or right side of the gauge.)
|
|
6= BarStyle (enumerated in InfoBox.barStyles ) --]]--
|
|
local args={...}
|
|
table.insert (self.Bars, index, {}) -- Add a table for new bar.
|
|
setmetatable(self.Bars[index],{__metatable={parent = self.Bar}, __index = idx, __newindex= newidx})
|
|
for i = index, #self.Bars do
|
|
self.Bars[i].id = i -- a way to find our index in the future
|
|
end
|
|
for k,v in ipairs(args) do -- update with optional parameters passed in
|
|
MiniWindow.Bar[ MiniWindow.Bar[k] ] (MiniWindow.Bars[index], v) -- This line of code is why MW.Bar[1] = "Caption". Bar[1] thru Bar[5] define which function the optional parameters call. Neat, hunh?
|
|
end
|
|
self:Resize()
|
|
return self.Bars[index]
|
|
end
|
|
|
|
--[=[ See :Doc( "RemoveBar" ) --]=]--
|
|
function _M:RemoveBar(index)
|
|
--TraceOut (string.format("%s: Window %s", "RemoveBar", self.windowName))
|
|
assert(self ~= _M , "Call from a table created from ".. _NAME .. ":New(), not ".. _NAME .. " itself.")
|
|
assert(self.parent == nil, "Attempt to remove a Bar from a Bar. Use table from ".. _NAME .. ":New() instead.")
|
|
assert(index, "Bars index must be passed.")
|
|
table.remove (self.Bars, index)
|
|
local otheraxis = {columns = "rows", rows = "columns"} -- Shrink the grid if appropriate
|
|
if (self[self.axis] -1 ) * self[ otheraxis[self.axis] ] >= #self.Bars then
|
|
self[self.axis] = self[self.axis] -1
|
|
self:Resize()
|
|
end
|
|
for i = index, #self.Bars do
|
|
self.Bars[i].id = i
|
|
end end
|
|
|
|
--[=[ See :Doc( "Update" ) --]=]--
|
|
function _M:Update (force)
|
|
--TraceOut (string.format("%s: Window %s", "Update", self.windowName))
|
|
assert(self ~= _M , "Pass a table called from ".. _NAME .. ":New(), not ".. _NAME .. " itself.")
|
|
--Note: It is possible to pass any table instance into this. i.e. foo, foo.Bar, foo.Bars[i]
|
|
--It may be bad style, but it intentionally will work. foo.Bars[i] still updates the entire window, not just its region.
|
|
if os.time() > (self.lastUpdated or 0) or force then
|
|
local MiniWindow = self.parent or self
|
|
check (WindowCreate (self.windowName, 0, 0, self.windowWidth, self.windowHeight, self.windowPosition, self.windowFlags, GetInfo(278)) )
|
|
check (WindowRectOp (self.windowName, 2, 2, 2, -2, -2, self.backgroundColour) ) -- "erase" miniwindw
|
|
local vertical,horizontal, curRow, curCol, t = 6, 0, 1, 1
|
|
for _, curBar in ipairs(self.Bars) do
|
|
local finishY = vertical + curBar.cellHeight + curBar.padding
|
|
if curRow > self.rows or finishY > self.windowHeight then
|
|
vertical = 6
|
|
curCol = curCol + 1
|
|
curRow = 1
|
|
if curCol > self.columns then --Maybe Fonts are distorting the grid
|
|
self:Resize() -- Resize/CalcWindowHeight will fix it
|
|
self:Update() -- and we need to redraw.
|
|
return -- and stop execution of the outdated update.
|
|
end end
|
|
horizontal = (curCol -1) * self.cellWidth
|
|
vertical = Draw(curBar, vertical, horizontal)
|
|
curRow=curRow+1
|
|
end
|
|
check (WindowRectOp (self.windowName, 5, 0, 1, -1, -2, 10, 15) ) -- 3D border effect on canvas
|
|
WindowRectOp (self.windowName, 2, self.windowWidth - 2 , 0, 0, 0, GetInfo(278), nil)
|
|
WindowShow (self.windowName, true)
|
|
self.lastUpdated = os.time()
|
|
return true
|
|
else
|
|
return false
|
|
end end
|
|
|
|
--[=[ See :Doc( "WindowPosition" ) --]=]--
|
|
function _M:WindowPosition(pos)
|
|
assert(type(pos) == "number" and (pos >= 4 and pos <=11), "Invalid window position passed. Use " .. _NAME .. ".windowPositions[ <N,S,E,W,NE...> ] if unsure.")
|
|
assert(self ~= _M and self.parent == nil, "Pass a table created from ".. _NAME .. ":New(), not ".. _NAME .. " itself.")
|
|
world.WindowPosition(self.windowName, 0,0,pos, self.windowFlags)
|
|
if ( (self.windowPosition == 5 or self.windowPosition == 9) and (pos ~= 5 and pos ~=9) or
|
|
(self.windowPosition ~= 5 and self.windowPosition ~= 9) and (pos == 5 or pos ==9) ) then
|
|
self.displaceOutput = (pos == 5 or pos == 9)
|
|
self.columns, self.rows = self.rows, self.columns
|
|
self.axis = "columns"
|
|
end
|
|
self.windowPosition = pos
|
|
self:Resize()
|
|
end
|
|
|
|
--[=[ See :Doc( "ResizeOutput" ) --]=]--
|
|
function _M:ResizeOutput()
|
|
local maxWidth, maxHeight = 0,0
|
|
local left, top, width, height = GetInfo(272), GetInfo(273), GetInfo(274), GetInfo(275)
|
|
local bOff, bCol, bWid, oCol, oSty = GetInfo(276), GetInfo(282), GetInfo(277), GetInfo(278), GetInfo(279)
|
|
local t={}
|
|
for _, v in ipairs(WindowList() or {}) do
|
|
local tmpPos, shown = WindowInfo(v, 7), WindowInfo(v,5)
|
|
if shown then
|
|
t[tmpPos] = (t[tmpPos] or 0) + 1
|
|
end end
|
|
local function sum (...)
|
|
local args, res= {...}, 0
|
|
for _,n in ipairs(args) do
|
|
if type(t[n]) == "number" then res = (res + t[n]) end
|
|
end
|
|
return res
|
|
end
|
|
if self.displaceOutput then
|
|
if self.windowPosition == 9 or self.windowPosition == 10 then
|
|
if sum(9,10) == 1 then
|
|
height = -self.windowHeight - 8
|
|
else
|
|
height = -math.max(math.abs(height), self.windowHeight)
|
|
end
|
|
elseif self.windowPosition == 11 then
|
|
if t[11] == 1 then
|
|
left = self.windowWidth
|
|
else
|
|
left = math.max ( left, self.windowWidth)
|
|
end
|
|
elseif self.windowPosition == 4 or self.windowPosition == 5 then
|
|
if sum(4,5) == 1 then
|
|
top = self.windowHeight
|
|
else
|
|
top = math.max( top , self.windowHeight)
|
|
end
|
|
else
|
|
if sum(6,7,8) == 1 then
|
|
width = -1 * self.windowWidth
|
|
else
|
|
width = -1 * math.max( math.abs(width) , self.windowWidth )
|
|
end end end
|
|
if sum(11) == 0 then left = 4 end
|
|
if sum(9,10) == 0 then height = 0 end
|
|
if sum(5, 4) == 0 then top = 0 end
|
|
if sum(6, 7, 8) == 0 then width = 0 end
|
|
TextRectangle(left, top, width, height, bOff, bCol, bWid, oCol, oSty)
|
|
end
|
|
|
|
--[=[ See :Doc( "Resize" ) --]=]--
|
|
function _M:Resize()
|
|
assert (self ~= _M , "Resize a window, not the module.")
|
|
assert (not self.parent, "Resize() is for MiniWindows, not Bars.")
|
|
local sharedWindow, winwidths = {}, 0
|
|
local sidewindows = {}
|
|
CalcWindowHeight(self)
|
|
if self.windowPosition == 5 or self.windowPosition == 9 then
|
|
local padptrn = "padS[EW]$"
|
|
if self.windowPosition == 5 then padptrn = "padN[EW]$" end
|
|
for _,v in ipairs(WindowList() ) do
|
|
if v:find(padptrn) then
|
|
WindowDelete(v)
|
|
elseif WindowInfo(v,5) then
|
|
local Position = WindowInfo(v, 7)
|
|
sidewindows[Position] = sidewindows[Position] or {topmost = 100000, bottommost = 0, leftmost = 100000, rightmost = 0, topwidth = 0, leftheight = 0, rightheight = 0}
|
|
sidewindows[Position].topmost = math.min( sidewindows[Position].topmost, WindowInfo(v, 11) )
|
|
sidewindows[Position].bottommost = math.max( sidewindows[Position].bottommost, WindowInfo(v, 13) )
|
|
sidewindows[Position].leftmost = math.min(sidewindows[Position].leftmost, WindowInfo(v, 10) )
|
|
sidewindows[Position].rightmost = math.max(sidewindows[Position].rightmost, WindowInfo(v, 12 ) )
|
|
if WindowInfo(v,11) == sidewindows[Position].topmost then
|
|
sidewindows[Position].topwidth = WindowInfo(v,3)
|
|
end
|
|
if Position == self.windowPosition then
|
|
sharedWindow[#sharedWindow +1] = v
|
|
sidewindows[Position].leftmost = math.min(sidewindows[Position].leftmost, WindowInfo(v, 10) )
|
|
sidewindows[Position].rightmost = math.max(sidewindows[Position].rightmost, WindowInfo(v, 12) )
|
|
if sidewindows[Position].leftmost == WindowInfo(v, 10) then
|
|
sidewindows[Position].leftheight = WindowInfo ( v, 4 )
|
|
end
|
|
if sidewindows[Position].rightmost == WindowInfo(v, 12) then
|
|
sidewindows[Position].rightheight = WindowInfo ( v, 4 )
|
|
end end end end
|
|
|
|
--[[ Prevent overlapping Auto-centered windows.
|
|
Windows will be arranged:
|
|
LttttR
|
|
L R
|
|
L R
|
|
BBBBBB --]]
|
|
|
|
if self.windowPosition == 5 then
|
|
if sidewindows[11] and sidewindows[11].topmost < sidewindows[5].bottommost then
|
|
sidewindows[4] = sidewindows[4] or {topwidth = 0 }
|
|
sidewindows[4].topwidth = math.max(sidewindows[4].topwidth, sidewindows[11].topwidth )
|
|
WindowCreate(self.windowName .. "padNW", 0,0,sidewindows[11].topwidth,0, 4, 0, 0)
|
|
WindowShow(self.windowName .. "padNW")
|
|
end
|
|
|
|
if sidewindows[7] and sidewindows[7].topmost < sidewindows[5].bottommost then
|
|
sidewindows[6] = sidewindows[6] or {topwidth = 0 }
|
|
sidewindows[6].topwidth = math.max(sidewindows[6].topwidth, sidewindows[7].topwidth )
|
|
WindowCreate(self.windowName .. "padNE", 0,0,sidewindows[7].topwidth,0, 6, 0, 0)
|
|
WindowShow(self.windowName .. "padNE")
|
|
end
|
|
elseif self.windowPosition == 9 then
|
|
if sidewindows[11] and sidewindows[11].bottommost > GetInfo(280) - sidewindows[9].leftheight then
|
|
WindowCreate(self.windowName .. "padSW", 0,0,0,sidewindows[9].leftheight, 10, 0, 0)
|
|
WindowShow(self.windowName .. "padSW")
|
|
end
|
|
if sidewindows[7] and sidewindows[7].bottommost > GetInfo(280) - sidewindows[9].rightheight then
|
|
WindowCreate(self.windowName .. "padSE", 0,0,0, sidewindows[9].rightheight, 8, 0, 0)
|
|
WindowShow(self.windowName .. "padSE")
|
|
end end
|
|
sidewindows[self.windowPosition -1] = sidewindows[self.windowPosition -1] or {topwidth = 0}
|
|
sidewindows[self.windowPosition +1] = sidewindows[self.windowPosition +1] or {topwidth = 0}
|
|
self.windowWidth = math.floor( (GetInfo(281) - sidewindows[self.windowPosition -1].topwidth - sidewindows[self.windowPosition +1].topwidth ) / #sharedWindow)
|
|
if WindowInfo(self.windowName, 6) then -- we're hidden and a sharedwindow isn't an infobox that will resize itself.
|
|
for _,p in ipairs({4,6,8,10}) do
|
|
sidewindows[p] = sidewindows[p] or {topwidth = 0}
|
|
end
|
|
winwidths = (sidewindows[self.windowPosition - 1].topwidth) + (sidewindows[self.windowPosition + 1].topwidth)
|
|
for _,v in ipairs(sharedWindow) do
|
|
if v ~= self.windowName then
|
|
winwidths = winwidths + WindowInfo(v,3)
|
|
end end
|
|
self.windowWidth = GetInfo(281) - winwidths
|
|
end end
|
|
self:ResizeOutput()
|
|
end
|
|
|
|
--[=[ See :Doc( "CloseWindow" ) --]=]--
|
|
function _M:CloseWindow ()
|
|
local wins = {"", "glass", "NE", "NW", "SE", "SW"}
|
|
for i = 1,5 do
|
|
WindowDelete(self.windowName .. wins[i])
|
|
self:ResizeOutput()
|
|
end end
|
|
|
|
--[=[ See :Doc( "Font" ) --]=]--
|
|
function _M:Font(...)
|
|
--[=[ Optional parameters:
|
|
-- Name, string
|
|
-- Size, number
|
|
-- Bold, boolean
|
|
-- Italic, boolean
|
|
-- Underline, boolean
|
|
-- Strikeout, boolean
|
|
-- Charset, number
|
|
-- PitchAndFamily, number
|
|
--]=]
|
|
assert(self ~= _M , "Pass a table created from ".. _NAME .. ":New(), not ".. _NAME .. " itself.")
|
|
local fontParams = {}
|
|
local gaugeRatio = (self.gaugeHeight or self.Bar.gaugeHeight) / (self.cellHeight or self.Bar.cellHeight)
|
|
for k,v in ipairs(fontProps) do fontParams[k] = self[v] end
|
|
local MiniWindow = self.parent or self
|
|
local args = {...}
|
|
if args[1] == nil then
|
|
if self == MiniWindow then
|
|
local defaultFont = {}
|
|
for _,f in ipairs(fontProps) do self[f] = nil ; defaultFont[#defaultFont +1] = self[f] end
|
|
check( WindowFont (self.windowName, unpack(defaultFont) ) )
|
|
self.fontHeight = WindowFontInfo (self.windowName, self.fontID, 1)
|
|
self.Bar.cellHeight = self.fontHeight + self.Bar.cellPadding
|
|
self.Bar.gaugeHeight = self.Bar.cellHeight * gaugeRatio
|
|
else
|
|
for _,f in ipairs(fontProps) do self[f] = nil end
|
|
self.fontHeight = nil
|
|
self.cellHeight = nil
|
|
self.gaugeHeight = self.cellHeight * gaugeRatio
|
|
end
|
|
else
|
|
for k,v in ipairs(args) do
|
|
fontParams[k + 1] = v
|
|
self[fontProps[k + 1] ] = v
|
|
end
|
|
self.fontName, self.fontSize = name, fontParams[1]
|
|
if self == MiniWindow then
|
|
MiniWindow.windowHeight = _M.windowHeight
|
|
check(WindowFont(MiniWindow.windowName, unpack(fontParams) ) )
|
|
MiniWindow.Bar.cellHeight = WindowFontInfo (MiniWindow.windowName, MiniWindow.fontID, 1) + MiniWindow.Bar.cellPadding
|
|
else
|
|
fontParams[1]= "f" .. self.id
|
|
check(WindowFont(self.windowName, unpack(fontParams) ) )
|
|
for k,v in ipairs(fontProps) do if fontParams[k] ~= self.parent[v] then self[v] = fontParams[k] end end
|
|
self.fontHeight = WindowFontInfo (self.windowName, self.fontID, 1)
|
|
self.cellHeight = self.fontHeight + self.cellPadding
|
|
self.gaugeHeight = self.cellHeight * gaugeRatio
|
|
end end
|
|
MiniWindow:Resize()
|
|
end
|
|
|
|
--[=[ See :Doc( "ReopenWindow" ) --]=]--
|
|
function _M:ReopenWindow()
|
|
local MiniWindow = self.parent or self
|
|
check(WindowCreate(MiniWindow.windowName, 0,0,MiniWindow.windowWidth,MiniWindow.windowHeight, MiniWindow.windowPosition, MiniWindow.windowFlags, MiniWindow.backgroundColour) )
|
|
WindowShow(MiniWindow.windowName)
|
|
MiniWindow:Resize()
|
|
local font = {}
|
|
for k,v in ipairs (fontProps) do font[k] = MiniWindow[v] end
|
|
WindowFont (MiniWindow.windowName, unpack(font))
|
|
for _, Bar in ipairs(MiniWindow.Bars) do
|
|
if Bar.fontID ~= MiniWindow.fontID then
|
|
for k,v in ipairs (fontProps) do font[k] = Bar[v] end
|
|
WindowFont (Bar.windowName, unpack(font))
|
|
end end
|
|
MiniWindow:Update()
|
|
end
|
|
|
|
--[=[ See :Doc( "CaptionPlacement" ) --]=]--
|
|
function _M:CaptionPlacement (x)
|
|
assert((self.id and x>=0 and x<=5) or (not self.parent and x ==nil),"call MiniWindow:CaptionPlacement() or Bar:CaptionPlacement(x), x must be a value in the ".. _NAME .. ".captionPlacements table. Got ".. tostring(x) .. " (" .. type(x) ..")")
|
|
local m, MiniWindow = 5, self.parent or self
|
|
if self.parent then self.captionPlacement = x end
|
|
local startCol, endCol, barID
|
|
if self.id then -- Hit just the column
|
|
startCol = math.modf(self.id/self.rows)
|
|
endCol = startCol
|
|
else -- Hit em all
|
|
startCol = 0
|
|
endCol = MiniWindow.columns -1
|
|
end
|
|
for curCol = startCol, endCol do
|
|
local maxCaplength, capsPlaced = 5, {}
|
|
barID = (curCol * self.rows) + 1
|
|
while curCol == math.modf( ( barID -1)/self.rows ) and barID <= #MiniWindow.Bars do
|
|
local cBar = MiniWindow.Bars[ barID ]
|
|
if cBar.barStyle ~= 0 then
|
|
maxCaplength = math.max(maxCaplength,WindowTextWidth(MiniWindow.windowName, cBar.fontID, strip_colours(cBar.caption), false)+5 )
|
|
capsPlaced[cBar.captionPlacement] = true
|
|
end
|
|
barID = barID +1
|
|
end
|
|
barID = (curCol * self.rows) + 1
|
|
while curCol == math.modf( (barID - 1)/self.rows ) and barID <= #MiniWindow.Bars do
|
|
local cBar = MiniWindow.Bars[ barID ]
|
|
if capsPlaced[0] and not capsPlaced[3] then
|
|
cBar.gaugeLeft = maxCaplength
|
|
cBar.gaugeWidth = MiniWindow.cellWidth - cBar.gaugeLeft -8
|
|
elseif not capsPlaced[0] and capsPlaced[3] then
|
|
cBar.gaugeLeft = nil
|
|
cBar.gaugeWidth = MiniWindow.cellWidth - maxCaplength -8
|
|
elseif capsPlaced[0] and capsPlaced[3] then
|
|
cBar.gaugeLeft = maxCaplength
|
|
cBar.gaugeWidth = MiniWindow.cellWidth - (2 * maxCaplength) - 2
|
|
else
|
|
cBar.gaugeLeft = nil
|
|
cBar.gaugeWidth = nil
|
|
end
|
|
barID = barID + 1
|
|
end end end
|
|
|
|
|
|
--[[-- Friend Functions --]]--
|
|
|
|
--[=[ Internal Function ]=]--
|
|
function CalcWindowHeight (self)
|
|
local MiniWindow = self.parent or self
|
|
local tmpHeights = {(MiniWindow.Bar.cellHeight + MiniWindow.Bar.padding) * MiniWindow.rows, 0}
|
|
local modOffset = 0
|
|
local otheraxis = {columns = "rows", rows = "columns"}
|
|
if MiniWindow[ otheraxis[MiniWindow.axis] ] == 0 then
|
|
MiniWindow[ otheraxis[MiniWindow.axis] ] = 1
|
|
end
|
|
if #MiniWindow.Bars > (MiniWindow.rows * MiniWindow.columns) then -- Is the grid big enough?
|
|
repeat
|
|
MiniWindow[MiniWindow.axis] = MiniWindow[MiniWindow.axis] + 1
|
|
until #MiniWindow.Bars <= MiniWindow.columns * MiniWindow.rows
|
|
end
|
|
|
|
MiniWindow:CaptionPlacement()
|
|
for _,tmpBar in ipairs(MiniWindow.Bars or {}) do -- Calculate the single largest column size.
|
|
if ( (tmpBar.id + modOffset) -1 ) % MiniWindow.rows == 0 then
|
|
tmpHeights[ #tmpHeights + 1 ] = tmpBar.cellHeight + tmpBar.padding
|
|
else
|
|
tmpHeights[#tmpHeights] = tmpHeights[#tmpHeights] + tmpBar.cellHeight + tmpBar.padding
|
|
end
|
|
if (tmpBar.cellHeight + tmpBar.padding) > (MiniWindow.Bar.cellHeight + MiniWindow.Bar.padding) and
|
|
#MiniWindow.Bars < (MiniWindow.rows*MiniWindow.columns) then
|
|
modOffset = -(tmpBar.id % MiniWindow.rows)
|
|
end
|
|
end
|
|
MiniWindow.windowHeight = math.max(unpack(tmpHeights) ) + _M.windowHeight
|
|
check (WindowCreate (MiniWindow.windowName, 0, 0, MiniWindow.windowWidth, MiniWindow.windowHeight, MiniWindow.windowPosition, MiniWindow.windowFlags, MiniWindow.backgroundColour) )
|
|
WindowShow(MiniWindow.windowName)
|
|
end
|
|
|
|
--[=[ Internal Function used in DoFade ]=]--
|
|
function SplitRGB (Colour)
|
|
local _, r,g,b
|
|
if type(Colour) == "number" or colour_names[Colour] then
|
|
_,_, b,g,r = string.format("%06x", (colour_names[Colour] or Colour) ):find("(%x%x)(%x%x)(%x%x)")
|
|
elseif (type(Colour) == "string") then --HTML Formatted string "#RRGGBB" or something similar
|
|
_,_, r,g,b = Colour:find("(%x%x)(%x%x)(%x%x)")
|
|
end
|
|
r,g,b = tonumber(r, 16), tonumber(g,16), tonumber(b,16)
|
|
return r,g,b , string.format("#%02x%02x%02x", r,g,b):upper()
|
|
end
|
|
|
|
--[=[ Internal Function used in DoFade ]=]--
|
|
function CalcShades(self, shades) -- the number of shades including start and end
|
|
local c, step, Cs = {}, {}, {}
|
|
local r1, g1, b1 = SplitRGB(self.goodColour)
|
|
local r2, g2, b2 = SplitRGB(self.badColour)
|
|
step.r = (r1-r2)/shades
|
|
step.g = (g1-g2)/shades
|
|
step.b = (b1-b2)/shades
|
|
for i = 0, shades do
|
|
Cs[i+1] = tonumber(string.format("%02x%02x%02x", math.floor(b1 - (step.b * i) ) % 256 , math.floor(g1 - (step.g * i) ) % 256 , math.floor(r1 - (step.r * i) ) % 256 ),16)
|
|
end
|
|
Cs[#Cs] = self.badColour
|
|
return Cs, step, step.r, step.g, step.b
|
|
end
|
|
|
|
--[=[ Internal Function used for color codes ]=]--
|
|
function capitalize (s)
|
|
return s:gsub("%a",string.upper, 1)
|
|
end -- capitalize
|
|
|
|
--[=[ Internal Function used in PrintText ]=]--
|
|
function strip_colours (s)
|
|
s=s or ""
|
|
s = s:gsub ("@@", "\0") -- change @@ to 0x00
|
|
s = s:gsub ("@.([^@]*)", "%1")
|
|
return (s:gsub ("%z", "@") ) -- put @ back
|
|
end
|
|
|
|
--[=[ Internal Function used in Caption, graciously borrowed from Nick Gammon ]=]--
|
|
function commas (num)
|
|
assert (type (num) == "number" or
|
|
type (num) == "string")
|
|
|
|
local result = ""
|
|
|
|
-- split number into 3 parts, eg. -1234.545e22
|
|
-- sign = + or -
|
|
-- before = 1234
|
|
-- after = .545e22
|
|
|
|
local sign, before, after =
|
|
string.match (tostring (num), "^([%+%-]?)(%d*)(%.?.*)$")
|
|
|
|
-- pull out batches of 3 digits from the end, put a comma before them
|
|
|
|
while string.len (before) > 3 do
|
|
result = "," .. string.sub (before, -3, -1) .. result
|
|
before = string.sub (before, 1, -4) -- remove last 3 digits
|
|
end -- while
|
|
|
|
-- we want the original sign, any left-over digits, the comma part,
|
|
-- and the stuff after the decimal point, if any
|
|
return sign .. before .. result .. after
|
|
|
|
end -- function commas
|
|
|
|
--[=[ Populates color codes tables ]=]--
|
|
for i,v in ipairs(ansiCodes) do
|
|
ansiColors[v] = GetNormalColour (i)
|
|
ansiColors[capitalize(v)] = GetBoldColour (i)
|
|
end
|
|
|
|
|
|
|
|
--[=[ Documentation - MW:Doc() will be easier to read then the source of the table ]=]--
|
|
|
|
_Doc = {
|
|
AddBar = [[
|
|
Applies To: MiniWindow table
|
|
Prototype: myBar = MW:AddBar(caption, value, goodColour, badColour, anchorRight, barStyle)
|
|
|
|
Adds a new bar to the end of the [MiniWindow].Bars table and returns a reference to this table.
|
|
|
|
caption = string; if a number is passed, commas are added to the ciphers
|
|
value = number; the percentage of the bar that is filled. Overmax percentages are accepted, and goodColour is drawn 15% brighter.
|
|
goodColour = string|number; the string is checked against names of colours or HTML formatting, the long number value of a color is also accepted.
|
|
badColour = string|number; same as goodColour
|
|
anchorRight = boolean; if true, 100% is on the left, 0% on the right. Automatically sets caption to be innerRight if true.
|
|
barStyle = number; a bitmask of barStyles values that specify a frame and fill type.]],
|
|
CaptionPlacement = [[
|
|
Applies To: Miniwindow table, Bar
|
|
Prototype: Bar:CaptionPlacement(n) or MW:CaptionPlacement()
|
|
|
|
Sets where text is drawn in the bar and calculates gauge sizes as appropriate. If calling against the MiniWindow itself, do not pass a parameter in the function to recalculate all gauge sizes and placements.
|
|
Setting a value to the MiniWindow.Bar.captionPlacement value will change the default label placement.
|
|
|
|
n = number; a value of 0-5 which are enumerated in the captionPlacements table.]],
|
|
CloseWindow = [[
|
|
Applies To: Miniwindow
|
|
Prototype: MW:CloseWindow()
|
|
|
|
Intended to be called from OnPluginDisable or OnPluginClose. Deletes the MiniWindow from MushClient's list of miniwindows.
|
|
Call MW:ReopenWindow() in the OnPluginEnable function.
|
|
]], --']]
|
|
Columns = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:Columns(n)
|
|
|
|
Sets the number of columns into which the miniwindow is divided.
|
|
|
|
n = number; The number of columns.]],
|
|
Font = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: MW:Font([fontName, fontSize, fontBold, fontItalic, fontUnderline, fontStrikeout, fontPitchAndFamily])
|
|
|
|
If no parameters are passed, deletes font settings on the specific object so it will reinherit from a parent object.
|
|
Parameters omitted will retrieve settings from those named values. Specified values set named value on object as well.
|
|
|
|
See MushClient documentation for "WindowFont" for information on parameters.]],
|
|
InsertBar = [[
|
|
Applies To: MiniWindow
|
|
Prototype: myBar = MW:InsertBar(n, caption, value, goodColour, badColour, anchorRight, barStyle)
|
|
|
|
Inserts a new bar at position n and returns a reference to this new bar table.
|
|
|
|
n = number; The 1-based index of the new bar.
|
|
caption = string; if a number is passed, commas are added to the ciphers
|
|
value = number; the percentage of the bar that is filled. Overmax percentages are accepted, and goodColour is drawn 15% brighter.
|
|
goodColour = string|number; the string is checked against names of colours or HTML formatting, the long number value of a color is also accepted.
|
|
badColour = string|number; same as goodColour
|
|
anchorRight = boolean; if true, 100% is on the left, 0% on the right. Automatically sets caption to be innerRight if true.
|
|
barStyle = number; a bitmask of barStyles values that specify a frame and fill type.]],
|
|
New = [[
|
|
Applies To: Module
|
|
Prototype: MW = ]] .. _NAME .. [[:New([name])
|
|
|
|
Creates a new miniwindow table for you to populate with bars. The returned table has a metatable with its __index value referencing ]] .. _NAME .. [[.
|
|
|
|
name = string; If specified, sets the name of the window returned by MushClient's WindowList function. Omitting this value generates a GUID for MushClient to use for the window name. This name is stored in the MW.windowName value.]], --']]
|
|
ReopenWindow = [[
|
|
Applies To: MiniWindow
|
|
Protoype: MW:ReopenWindow()
|
|
|
|
Intended to be used in the OnPluginEnabled callback so that fonts are reloaded after the miniwindow is deleted with WindowDelete() (i.e. OnPluginDisabled called MW:CloseWindow() (but not MW = nil) which deletes the window from WindowList(). ]],
|
|
RemoveBar = [[
|
|
Applies To: MiniWindow
|
|
Prototype: MW:RemoveBar(n)
|
|
|
|
Deletes the specified bar from the Bars table.
|
|
|
|
n = number; The index of the bar to delete. A bar stores its index in the Bar.id value for your convenience.]],
|
|
Resize = [[
|
|
Applies To: MiniWindow
|
|
Prototype: MW:Resize()
|
|
|
|
This is called internally when necessary, the only time you need to be aware of it is for windows positioned at the top-center or bottom-center of the screen since they grow to the available width. It is recommended to place a call in the OnPluginWorldOutputResized callback in this scenario.]],
|
|
ResizeOutput = [[
|
|
Applies To: MiniWindow
|
|
Prototype: MW:ResizeOutput()
|
|
|
|
Called internally when positioning miniwindows at the left-center, lower-left, or bottom-center positions. Ff you wish another window to resize the Mud's text area, call it manually after setting that Miniwindow's .displaceOutput value to true.]], --']]
|
|
Rows = [[
|
|
Applies To: MiniWindow
|
|
Prototype: MW:Rows(n)
|
|
|
|
Sets the number of rows in a miniwindow to a specific value. If the MW.axis value is equal to "rows" it may still grow when new bars exceed the available space.
|
|
|
|
n = number; A positive number of rows]],
|
|
Update = [[
|
|
Applies To: MiniWindow
|
|
Prototype: updated = MW:Update()
|
|
|
|
Draws or redraws the Miniwindow. This function will only redraw once a second to prevent excessive CPU utilization during speedwalk or lagbursts.
|
|
|
|
updated = boolean; True if the window was redrawn this call, false if it had been drawn already in the past second and not updated.]],
|
|
WindowPosition = [[
|
|
Applies To: MiniWindow
|
|
Prototype: MW:WindowPosition(n)
|
|
|
|
Sets the location for the MiniWindow.
|
|
|
|
n = number; a value between 4 and 11. Values are enumerated in the .windowPositions table.]],
|
|
axis = [[
|
|
Applies To: MiniWindow
|
|
ProtoType: MW.axis = <"rows"|"columns">
|
|
|
|
Determines which way the grid scales as new bars demand additional space. MW.windowHeight grows as new rows are added. MW.windowWidth remains the same as new columns divide that space into smaller pieces.]],
|
|
backgroundColour = [[
|
|
Applies To: MiniWindow
|
|
ProtoType: MW.backgroundColour = n
|
|
|
|
The colour of the miniwindow.
|
|
|
|
n = number; The number value of the colour desired. i.e. colour_names.indigo, not "indigo"]],
|
|
barStyles = [[
|
|
Applies To: All
|
|
Prototype: N/A
|
|
|
|
A table enumerating the possible barStyle fills and frames.
|
|
|
|
none = 0; no frame
|
|
sunken = 1; a raised bar in a recessed frame
|
|
raised = 2; a recessed bar in a raised frame
|
|
raisedCap = 4; a recessed bar in a raised frame that fills the whole cell, regardless of captionPlacement
|
|
flat = 8; a single pixel frame, untouched gauge effect
|
|
glass = 16; recessed frame and a pretty visual effect on the bar
|
|
|
|
solid = 32; a plain color fill
|
|
gradientScale = 64; a gradient that goes from 0 to .value
|
|
gradientFixed = 128; gradient goes from 0 to 100, with backgroundColour covering .value +1 to 100
|
|
gradientShift = 256; The thermometer effect. Gradient that has its midpoint at .value.]],
|
|
captionPlacements = [[
|
|
Applies To: ALL
|
|
Prototype: N/A
|
|
|
|
A table enumerating values for the location of labels.
|
|
|
|
left = 0; Text is drawn to the left of the gauge.
|
|
innerLeft = 1; Text is drawn left justified close to the 0 value
|
|
innerRight = 2; Text is drawn right justified by the 100 value
|
|
right = 3; Text is drawn to the right of the gauge
|
|
center = 4; Text is drawn centered within the gauge.
|
|
centerCell = 5; Text is drawn centered within the entire bar.]],
|
|
columns = [[Applies To: MiniWindow
|
|
Prototype: MW.columns = n
|
|
|
|
The number of columns the MW is divided into. Setting this value directly bypasses validation in the Columns function.
|
|
|
|
n = number; Expected to be a positive, non-zero integer.]],
|
|
customColourCodes = [[
|
|
Applies to: MiniWindow, Bar
|
|
Prototype: Bar.customColourCodes = {a=val, [b=val2, ...]}
|
|
|
|
A table used for drawing different colours within the caption. See caption for more information.
|
|
|
|
a = char; a single character key identifying the attached value.
|
|
val = number; the number value of the desired colour. i.e. {i= colour_names.indigo}]],
|
|
displaceOutput = [[
|
|
Applies To: MiniWindow
|
|
Prototype: MW.displaceOutput = bool
|
|
|
|
Set to true and call MW:ResizeOutput() if you want to shrink the area that mud text arrives in so your window doesn't float above it. MiniWindows placed at the left-center, lower-left, or bottom-center (W,SW,S positions) automatically set this value to true.]], --']]
|
|
fontBold = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: Bar.fontBold = bool
|
|
|
|
This property can be used to specify the default value for the Font function, or be used to retrieve its last set value.]],
|
|
fontCharset = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: Bar.fontCharset = bool
|
|
|
|
This property can be used to specify the default value for the Font function, or be used to retrieve its last set value.
|
|
See MushClient's WindowFont documentation for more information]], --']]
|
|
fontID = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: foo = Bar.fontID
|
|
|
|
This property is used internally and really shouldn't be needed in your scripting.]], --']]
|
|
fontItalic = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: Bar.fontItalic = bool
|
|
|
|
This property can be used to specify the default value for the Font function, or be used to retrieve its last set value.
|
|
See MushClient's WindowFont documentation for more information]], --']]
|
|
fontName = [[
|
|
Applies To: Module and MiniWindow, Bar
|
|
ProtoType: ]].._NAME..[[.fontName = "font name" | foo = MW.fontName | foo = Bar.fontName
|
|
|
|
You can change the fontName property on the module which will affect MiniWindows subsequently returned by the New() function.
|
|
This property on MiniWindows and Bars shouldn't be changed by your scripting directly. Use the Font() function to change the loaded font.]], --']]
|
|
fontPadding = [[
|
|
Applies To: ALL
|
|
Prototype: MW.fontPadding = n
|
|
|
|
The number of pixels to offset the font placement from the top of the cell.]],
|
|
fontPitchAndFamily = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: Bar.fontPitchAndFamily = number
|
|
|
|
This property can be used to specify the default value for the Font function, or be used to retrieve its last set value.
|
|
See MushClient's WindowFont documentation for more information]], --']]
|
|
fontSize = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: Bar.fontSize = bool
|
|
|
|
This property can be used to specify the default value for the Font function, or be used to retrieve its last set value.
|
|
See MushClient's WindowFont documentation for more information]], --']]
|
|
fontStrikeout = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: Bar.fontStrikeout = bool
|
|
|
|
This property can be used to specify the default value for the Font function, or be used to retrieve its last set value.
|
|
See MushClient's WindowFont documentation for more information]], --']]
|
|
fontUnderline = [[
|
|
Applies To: MiniWindow, Bar
|
|
Prototype: Bar.fontUnderline = bool
|
|
|
|
This property can be used to specify the default value for the Font function, or be used to retrieve its last set value.
|
|
See MushClient's WindowFont documentation for more information]], --']]
|
|
rows = [[
|
|
Applies To: MiniWindow
|
|
Prototype: MW.rows = n
|
|
|
|
The number of rows. Setting this value directly bypasses validation in the Rows function.
|
|
|
|
n = number; Expected to be a positive, non-zero integer.]],
|
|
textStyle = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.textStyle = n
|
|
|
|
The adornment on the caption text.
|
|
|
|
n = number; Expected values range from 0-5. See textStyles for more information]],
|
|
textStyles = [[
|
|
Applies To: All
|
|
Prototype: N/A
|
|
|
|
The table that enumerates textStyle values. Matting can be added to the other text styles for a little more clarity.
|
|
|
|
plain = 0;
|
|
matte = 1;
|
|
raised = 2;
|
|
sunken = 4;]],
|
|
windowFlags = [[
|
|
Applies To: Module, MiniWindow
|
|
Prototype: ]].._NAME..[[.windowFlags = n
|
|
|
|
Flags passed to the MushClient WindowCreate function. See MushClient documentation for more information.]],
|
|
windowHeight = [[
|
|
Applies To: Module, MiniWindow
|
|
Prototype: N/A
|
|
|
|
The MiniWindow.windowHeight is set dynamically to be .rows * .cellHeight + some padding. Setting this value manually is not recommended.]],
|
|
windowPosition = [[
|
|
Applies To: Module, MiniWindow
|
|
Prototype: ]].._NAME..[[.windowPosition = n
|
|
|
|
Setting this on the module will set the initial placement of all MiniWindows returned by the New() function. It is recommended to not set this value directly on MiniWindows, instead use the MW:WindowPosition() function.
|
|
|
|
n= number; Expected values range from 4-11. See windowPositions table for more information.]],
|
|
windowPositions = [[
|
|
Applies To: All
|
|
Prototype: N/A
|
|
|
|
Table enumerating windowPosition values. Placements are named after the cardinal points of the compass.
|
|
|
|
NE = 4;
|
|
N = 5;
|
|
NW = 6;
|
|
E = 7;
|
|
SE = 8;
|
|
S = 9;
|
|
SW = 10;
|
|
W = 11;]],
|
|
windowWidth = [[
|
|
Applies To: Module, MiniWindow
|
|
Prototype: MW.windowWidth = n
|
|
|
|
The Number of pixels the miniwindow is wide.
|
|
|
|
n = number; Expected to be a positive integer]],
|
|
AnchorRight = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:AnchorRight(bool)
|
|
|
|
If True, then the 0 value is drawn on the right side of the gauge and captionPlacement, if set to innerLeft, is set to innerRight.]],
|
|
BadColour = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:BadColour(colour)
|
|
|
|
Set the color for close to 0 values.
|
|
|
|
colour = string|number; colour can be the name of a color ("red"), an HTML formatted string ("#FF0000"), or a number (255)]],
|
|
BarStyle = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:BarStyle(n)
|
|
|
|
A bitmask number representing the frame + fill desired for the bar.
|
|
|
|
n = number; 0 is text only, see barStyles for other values]],
|
|
Caption = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:Caption(label)
|
|
|
|
Sets the text for the bar. If label is a number, commas are added for readability.
|
|
|
|
label = string|number; The desired text to print.]],
|
|
ColourText = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:ColourText(val, threshold, good, bad [, neut])
|
|
|
|
Sets the textColour value to specified color.
|
|
Last three paramters can be specified as a name of a color ("red"), an HTML formatted string ("#FF0000"), or a number (255)
|
|
|
|
val = number; The value to be checked.
|
|
threshold = number; the value to check against.
|
|
good :: val > threshold (or val >=threshold if neut is not specified)
|
|
bad :: val < threshold
|
|
neut :: val == threshold]],
|
|
GoodColour = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:GoodColour(val)
|
|
|
|
The color for solid bars with value > threshold, or the non-zero side of gradients.]],
|
|
Padding = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:Padding(n)
|
|
|
|
The number of pixels to add to the bottom of a gauge before drawing the next gauge in the column.
|
|
|
|
n = number; A number of pixels. Negative values will cause overlapping gauges.]],
|
|
TextColour = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:TextColour(val)
|
|
|
|
The default color for text to be printed in if no other colour codes are specified in the caption value. If colour codes are specified, this function sets the value of the @~ identifier.
|
|
|
|
val = string|number; name of a color ("red"), an HTML formatted string ("#FF0000"), or a number (255)]],
|
|
TextStyle = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:TextStyle(n)
|
|
|
|
Sets the adornments to printed text.
|
|
|
|
n = number; value from 0-5. see textStyles for more information.]],
|
|
Threshold = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:Threshold(n)
|
|
|
|
Sets the value that goodColour transitions to badColour for bars with a solid barstyle, or sets where the midpoint of the gradient is for gradientFixed barstyles.
|
|
|
|
n = number; a value from 0 to 100.]],
|
|
Value = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:Value(n)
|
|
|
|
Sets what percent of the gauge is filled. Values over 100 will be drawn as 100% with goodColour 15% brighter, if possible.
|
|
|
|
n = number; Percent to draw in the gauge. ]],
|
|
WatchCaption = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:WatchCaption(varname)
|
|
|
|
Specifies the name of a variable that contains the text displayed for a given bar. Unlike the Caption function, a variable containing a number will not display the additional commas.
|
|
|
|
varname = string; the name of a variable. ("foo", "tbl.foo")]],
|
|
WatchValue = [[
|
|
Applies To: Bar
|
|
Prototype: Bar:WatchValue(varname)
|
|
|
|
Specifies the name of a variable that contains the percent of the gauge to draw.
|
|
|
|
varname = string; the name of a variable. ("percentHP", "tbl.nested[fighterhealth]")]],
|
|
anchorRight = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.anchorRight = bool
|
|
|
|
Value that determines which side of the gauge has the 0 value. You can set this value directly safely to a boolean value. ]],
|
|
badColour = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.badColour = n
|
|
|
|
The number value of the color drawn near 0 values for gradients, or when value is less than or equal to threshold for solid fills. The BadColour function sets this value to the number equivalent to a color.
|
|
Bar:BadColour("indigo") -- ok
|
|
Bar.badColour = 8519755 -- ok
|
|
Bar.badColour = "indigo" -- NOT OK!!!!
|
|
|
|
n = number; the number value for a colour.]],
|
|
barStyle = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.barStyle = n
|
|
|
|
The bitmasked number determining how a bar is drawn. See barStyles for the enumeration of possible styles.
|
|
|
|
n= number;]],
|
|
caption = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.caption = txt
|
|
|
|
The text to display for a bar's label. This value does not modify numbers when printing.
|
|
Bar:Caption(1000) --> prints 1,000
|
|
Bar.caption = 1000 --> prints 1000
|
|
|
|
Additional color settings can be specified with an "@x" delimiter where x is a single character. The 16 default ansi colors are taken from MushClient's settings and are set to c,m,y,k,r,g,b,w and their bold values C,M,Y,K... The colour that's in the textColour value can be referred to with "@~". Additional colours can be specified by adding a table to the customColourCodes value with a single character key, and the number value of the colour.
|
|
"@@" is needed to actually print an @ symbol in a caption.
|
|
i.e.:
|
|
MW.customColourCodes = {z = 255}
|
|
MW.Bars[2].customColourCodes = {z = 128}
|
|
MW.Bars[1].caption = "@zVery Red"
|
|
MW.Bars[2].caption = "@zNot so red"
|
|
MW.Bars[3].caption = "@zVery Red @~textColour Colour"
|
|
|
|
txt = string; the label.]], --']]
|
|
captionPlacement = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.captionPlacement = n
|
|
|
|
The value of where the caption is placed. It is recommended to set this value with the CaptionPlacement() function instead of setting the value directly.
|
|
|
|
n = number; a value ranging from 0 to 5]],
|
|
cellHeight = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.cellHeight = n
|
|
|
|
The number of pixels from the top of the bar to the bottom of the gauge. Note that the padding value is added to this to determine the top of the following gauge. This value is calculated dynamically when a font is loaded.
|
|
This should be a lesser used value since it is mostly handled internally.
|
|
n = number; ]],
|
|
cellPadding = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.cellPadding = n
|
|
|
|
Used mostly internally, this value is added to the height of a font to make the gauge a little bigger. It is only used to calculate cellHeight when a font is loaded.
|
|
|
|
n = number; number of pixels]],
|
|
gaugeHeight = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.gaugeHeight = n
|
|
|
|
Value that determines the top edge of the gauge. The internal draw routine uses cellHeight - gaugeHeight to determine coordinates for drawing so that gauges are naturally aligned to the bottom of the cell.
|
|
|
|
n = number; the number of pixels high a gauge should be]],
|
|
gaugeLeft = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.gaugeLeft = n
|
|
|
|
The number of pixels the gauge appears from the edge of the cell. Recalculated automatically by the CaptionPlacement function.
|
|
|
|
n = number; number of pixels.]],
|
|
goodColour = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.goodColour = n
|
|
|
|
The number value of the color drawn near 100% values for gradients, or when value is greater than threshold for solid fills. The GoodColour function sets this value to the number equivalent to a color.
|
|
Bar:GoodColour("indigo") -- ok
|
|
Bar.goodColour = 8519755 -- ok
|
|
Bar.goodColour = "indigo" -- NOT OK!
|
|
|
|
n = number; the number value for a colour.]],
|
|
padding = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.padding = n
|
|
|
|
The number of pixels from the bottom of this gauge to the top of the next cell.
|
|
|
|
n = number; numberof pixels]],
|
|
textColour = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.textColour = n
|
|
|
|
The number value of the colour for printed text. If there are no colour codes specified in the caption. See caption for more information.]],
|
|
textStyle = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.textStyle = n
|
|
|
|
n = number; 0-5. see textStyles for details.]],
|
|
threshold = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.threshold = n
|
|
|
|
The percentage value where goodColour changes to badColour for solid fills, or where the midpoint of the gradient is for gradientFixed fills.
|
|
|
|
n = number; ]],
|
|
value = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.value = n
|
|
|
|
The percentage of the bar to draw. Values greater than 100% will draw as 100% with the colour 15% brighter, if possible. Values lower than 0 don't draw.
|
|
|
|
n = number; percent of gauge to draw]], --']]
|
|
id = [[
|
|
Applies To: Bar
|
|
Prototype: Bar.id = n
|
|
|
|
It is recommended that you don't change this value. It is maintained internally. This value contains the index of this bar in the Bars table. It is useful for situations where you're dynamically adding and removing bars but kept a variable reference returned from the AddBar or InsertBar functions and may have lost track of which index this bar may be.]],
|
|
Bar = [[
|
|
Applies To: MiniWindow, Module
|
|
Prototype: MW.Bar = {...}
|
|
|
|
The Bar table contains the default values for newly created bars. A newly created Miniwindow (returned from the ]].._NAME..[[:New() function) has a new table with the values from ]].._NAME..[[.Bar copied into it. This table has a metatable with its __index value referring to the miniwindow that contains it.]],
|
|
Bars = [[
|
|
Applies To: MiniWindow
|
|
Prototype: MW.Bars = {...}
|
|
|
|
The Bars table contains nested tables of duplicated Bar tables with customized values. The Update function gets the settings for what to draw by looping through the Bars table's subtables. ]], --']]
|
|
gaugeWidth = [[Applies To: Bar
|
|
Prototype: Bar.gaugeWidth = n
|
|
|
|
The number of pixels the gauge extends within a bar. This property's default value is implemented in a metatable to dynamically return the appropriate width. Setting a value trumps the __index calculation, of course.
|
|
|
|
n = number; the number of pixels from the left edge ot the gauge to the right edge.]], --']]
|
|
["*Inheritance"] = [[Applies To: General Info
|
|
Prototype: N/A
|
|
|
|
This topic does not relate to one specific value or function. Its purpose is to document how the the metatables __index link.
|
|
Assuming:
|
|
MW = InfoBox:New()
|
|
MW:AddBar("Test")
|
|
print (MW.Bars[1].foo)
|
|
|
|
will search for a value foo in
|
|
MW.Bars[1],
|
|
MW.Bar,
|
|
MW,
|
|
then InfoBox
|
|
]],
|
|
|
|
["button"] =[[
|
|
Applies To: Bar
|
|
Protoype: bar.button = {mouseUp = "funcname", ...}
|
|
|
|
|
|
This value expects a table with certain keys paired to the _names_ of functions you write. If there is a table present a Hotspot is added that is drawn over the entire region of the cell (not just the gauge).
|
|
Missing keys are fine. (i.e. {mouseUp="f"} is OK. {mouseUp="f", mouseDown="", cancelMouseDown=""... is not necessary.)
|
|
|
|
Expected keys are named:
|
|
mouseUp
|
|
mouseDown
|
|
cancelMouseDown
|
|
tooltipText
|
|
mouseOver
|
|
cancelMouseOver
|
|
cursor
|
|
|
|
Your functions should be structured as:
|
|
function myClickFunction (flags, strBarsIndex)
|
|
local id = tonumber(strBarsIndex) -- because tbl["1"] is a different key than tbl[1]
|
|
...
|
|
MW.Bars[id].caption = "Clicked"
|
|
end
|
|
]],
|
|
|
|
["cellTop"] =[[
|
|
Applies To: Bar
|
|
Protoype: x = bar.cellTop
|
|
|
|
This value is set by the Update function. It is provided if you wish to add any custom coding and need to know where a bar was drawn. Setting this value produces no effect and will be overwritten the next time the Update function is called.
|
|
]],
|
|
|
|
["cellLeft"] =[[
|
|
Applies To: Bar
|
|
Protoype: x = bar.cellLeft
|
|
|
|
This value is set by the Update function. It is provided if you wish to add any custom coding and need to know where a bar was drawn. Setting this value produces no effect and will be overwritten the next time the Update function is called.
|
|
]],
|
|
|
|
["Fade"] =[[
|
|
Applies To: Bar
|
|
Protoype: bar:Fade(bool)
|
|
|
|
Calling this function sets the fade value and recalculates the shades table to which the fade effect refers. It's not required to call this function, since the draw routine will recalculate the shades table if necessary. There is an interesting bug that can be exploited by calling this function however.
|
|
|
|
Try the following:
|
|
for x = 100,30,-10 do
|
|
local foo = MW:AddBar("", x, "green", "red", false, MW.barStyles.glass + MW.barStyles.gradientScale)
|
|
foo:Fade(true)
|
|
foo.badColour = colour_names.dodgerblue
|
|
end
|
|
|
|
It's a bug, but it looks cool. Also this is why using the functions to set values is recommended!
|
|
]],
|
|
|
|
["cellWidth"] =[[
|
|
Applies To: Bar
|
|
Protoype: x = bar.cellWidth
|
|
|
|
The value for this property is generated by the Miniwindow's __index metamethod. The function in the metamethod returns (windowWidth / columns) for you. You should never have a reason to set your own value, and doing so will probably break things in uncool ways.
|
|
]], --']]
|
|
|
|
["*AddYourOwn"] =[[
|
|
Applies To: ALL
|
|
Protoype: N/A
|
|
|
|
A Bar is a table, after all, and you might find it useful to attach your own data, or a reference, to a bar. This is mostly safe to do as the module uses the pairs() and ipairs() functions in limited places.
|
|
pairs() is used to copy InfoBox.Bar to MW.Bar
|
|
ipairs() is used on the MW.Bar table to find the functions for the default parameters for AddBar.
|
|
ipairs() is used on the MW.Bars table to draw the bars.
|
|
|
|
Other than avoiding numerical indices in the 2 Bar(s) tables, it should be safe to add to a table as you see fit.
|
|
]],
|
|
|
|
--[=[
|
|
[""] =[[
|
|
Applies To:
|
|
Protoype:
|
|
|
|
|
|
]],
|
|
|
|
--]=]-- ']]
|
|
}
|
|
|
|
function Doc (self, topic)
|
|
if topic and _Doc[topic] then
|
|
print()
|
|
print (_Doc[topic],"\n")
|
|
else
|
|
local p = require "pairsByKeys"
|
|
print ("\nAdditional help can be found on the following functions and values\n")
|
|
local t , i={}, 0
|
|
for k,v in p(_Doc) do -- t[#t+1] = k end
|
|
local s= "%-20s"
|
|
i = i+1
|
|
Tell(s:format(k))
|
|
if i == 4 then
|
|
print()
|
|
i=0
|
|
end end
|
|
print("\n\nSyntax: ".. GetInfo(36) .. _NAME .. ':Doc("topic")\n')
|
|
end end
|