Skip to content

Commit 25e0958

Browse files
committed
Updated InfoBox.lua module - thanks to Willfa
1 parent 2387aa3 commit 25e0958

File tree

1 file changed

+148
-42
lines changed

1 file changed

+148
-42
lines changed

lua/InfoBox.lua

Lines changed: 148 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
--[[--
2-
InfoBox.lua version 1.1
1+
--[=[--
2+
InfoBox.lua version 1.2
33
Encapsulates and enhances Infobar functionality into miniwindows; gauges and status text.
4-
01-DEc-08
4+
14-DEc-08
55
66
by: WillFa (Spellbound on 3k.org:3000)
77
portions borrowed or adapted from samples by Nick Gammon.
88
99
License: Free for public use in your MushClient plugins and scripts as long as credit for this module is
1010
attributed to WillFa, and Nick Gammon.
1111
12+
Assumes that the Sylfaen font is installed on the system. Change line 67 if it is not.
13+
1214
Requires: MushClient v. 4.37+ for complete functionality. (CloseWindow() uses DeleteWindow MC function.)
1315
MushClient v. 4.35+ for basic functionality. (WindowGradient calls)
1416
@@ -28,11 +30,11 @@ Usage:
2830
2931
General Usage is more easily deduced by tprint(InfoBox), tprint(MW), tprint(MW.Bar) rather than reading this source.
3032
The metatables are setup in such a way that tprint will not recurse up the inheritance chain and spam you.
31-
--]]--
33+
--]=]--
3234

3335
local world, colour_names = world, colour_names, _M
3436
local os = {time = os.time}
35-
local math, string, table, bit, utils = math, string, table, bit, utils
37+
local math, string, table, bit = math, string, table, bit
3638
local tonumber, tostring, rawget, rawset, type, print = tonumber, tostring, rawget, rawset, type, print
3739
local unpack, assert, require, getmetatable, setmetatable = unpack, assert, require, getmetatable, setmetatable
3840
local pairs, ipairs, check = pairs, ipairs, check
@@ -62,19 +64,7 @@ windowPosition = 7
6264
windowFlags = 0
6365

6466
fontID = "fn"
65-
66-
local fonts = utils.getfontfamilies ()
67-
68-
if fonts.Sylfaen then
69-
fontName = "Sylfaen"
70-
elseif fonts.Dina then
71-
fontName = "Dina"
72-
elseif fonts ["Lucida Sans Unicode"] then
73-
fontName = "Lucida Sans Unicode"
74-
else
75-
fontName = "Courier"
76-
end -- if
77-
67+
fontName = "Sylfaen"
7868
fontSize = 10
7969
fontPadding = 2
8070
fontBold = true
@@ -245,6 +235,8 @@ end end
245235
--[=[ Internal Function that draws the pretty boxes ]=]--
246236
function Draw (self, vOffset, hOffset)
247237
--TraceOut (string.format("%s: Window %s Bar %i", "Draw", self.windowName, self.id))
238+
self.cellTop, self.cellLeft = vOffset , hOffset
239+
WindowRectOp (self.windowName , 2, self.cellLeft, self.cellTop - 1 , self.cellLeft + self.cellWidth , self.cellTop + self.cellHeight + self.padding - 2 , self.backgroundColour, nil)
248240
local Percent = self.value or 0
249241
local colour, fcolour
250242
if Percent < self.threshold then
@@ -264,11 +256,11 @@ function Draw (self, vOffset, hOffset)
264256
local pixels = self.gaugeWidth * Percent / 100
265257
if self.barStyle > 0 then
266258
local bezel = {[true] = 10, [false] = 5}
267-
local frameLeft = hOffset + self.gaugeLeft
268-
local frameTop = vOffset + self.cellHeight - self.gaugeHeight
269-
local frameRight = hOffset + self.gaugeLeft + self.gaugeWidth
270-
local frameBottom = vOffset + self.cellHeight
271-
local topX, topY, bottomX, bottomY = frameLeft + 2, frameTop + 2 , hOffset + self.gaugeLeft + pixels, frameBottom - 2
259+
local frameLeft = self.cellLeft + self.gaugeLeft
260+
local frameTop = self.cellTop + self.cellHeight - self.gaugeHeight
261+
local frameRight = self.cellLeft + self.gaugeLeft + self.gaugeWidth
262+
local frameBottom = self.cellTop + self.cellHeight
263+
local topX, topY, bottomX, bottomY = frameLeft + 2, frameTop + 2 , self.cellLeft + self.gaugeLeft + pixels, frameBottom - 2
272264
local colorL, colorR = self.badColour, (fcolour or self.goodColour)
273265
local ftopX, ftopY, fbottomX, fbottomY = bottomX + 1, frameTop, frameRight, frameBottom --fill region for fixed gradients
274266
if self.anchorRight == true then
@@ -280,9 +272,9 @@ function Draw (self, vOffset, hOffset)
280272
end
281273
if bit.band(barStyles.raisedCap, self.barStyle) == barStyles.raisedCap then
282274
if self.captionPlacement == 0 then
283-
frameLeft = hOffset + 3
275+
frameLeft = self.cellLeft + 3
284276
elseif self.captionPlacement == 3 then
285-
frameRight = hOffset + self.cellWidth -3
277+
frameRight = self.cellLeft + self.cellWidth -3
286278
end end
287279
if Percent >= 1 then
288280
if CheckStyle(self, self.barStyles.solid) then
@@ -297,12 +289,12 @@ function Draw (self, vOffset, hOffset)
297289
check (WindowRectOp (self.parent.windowName, 2, topX , topY , bottomX, bottomY, padFillColour) )
298290
if ( (self.anchorRight == false) and (self.threshold <= 50) ) or
299291
( (self.anchorRight == true) and (self.threshold > 50) ) then --need more colorR than colorL
300-
check (WindowGradient (self.parent.windowName, hOffset + self.gaugeLeft, frameTop, frameRight - padWidth, bottomY, colorL, colorR, 1 ) )
292+
check (WindowGradient (self.parent.windowName, self.cellLeft + self.gaugeLeft, frameTop, frameRight - padWidth, bottomY, colorL, colorR, 1 ) )
301293
elseif ( (self.anchorRight == true) and (self.threshold <= 50) ) or
302294
( (self.anchorRight == false) and (self.threshold > 50) ) then --need more colorL than colorR
303-
check (WindowGradient (self.parent.windowName, hOffset + self.gaugeLeft + padWidth, topY, frameRight -2, bottomY, colorL, colorR, 1 ) )
295+
check (WindowGradient (self.parent.windowName, self.cellLeft + self.gaugeLeft + padWidth, topY, frameRight -2, bottomY, colorL, colorR, 1 ) )
304296
end
305-
check (WindowRectOp (self.parent.windowName, 2, ftopX , ftopY , fbottomX , fbottomY -1 , self.parent.backgroundColour) )
297+
check (WindowRectOp (self.parent.windowName, 2, ftopX , ftopY , fbottomX , fbottomY -1 , self.backgroundColour) )
306298
elseif CheckStyle(self, self.barStyles.gradientShift) then -- Thermometer gradients.
307299
local midpointX = bottomX
308300
local pixel = self.gaugeWidth / 100
@@ -314,8 +306,8 @@ function Draw (self, vOffset, hOffset)
314306
check (WindowRectOp (self.parent.windowName, 2, topX , topY , bottomX , bottomY, (fcolour or self.goodColour) ) )
315307
check (WindowRectOp (self.parent.windowName, 2, ftopX, ftopY , fbottomX, bottomY, self.badColour) )
316308
check (WindowGradient (self.parent.windowName, midpointX - gradientWidth, topY, midpointX + gradientWidth, bottomY, colorR, colorL, 1 ) )
317-
check (WindowRectOp (self.parent.windowName, 2, hOffset + 1, vOffset, hOffset + self.gaugeLeft, vOffset + self.cellHeight , self.parent.backgroundColour) )
318-
check (WindowRectOp (self.parent.windowName, 2, frameRight, frameTop, -2, frameBottom, self.parent.backgroundColour) )
309+
check (WindowRectOp (self.parent.windowName, 2, self.cellLeft + 1, self.cellTop, self.cellLeft + self.gaugeLeft, self.cellTop + self.cellHeight , self.backgroundColour) )
310+
check (WindowRectOp (self.parent.windowName, 2, frameRight, frameTop, -2, frameBottom, self.backgroundColour) )
319311
end
320312
if CheckStyle(self, self.barStyles.glass) then -- glass frame
321313
local glassWidth, dtX,dtY, dbX, dbY = pixels, topX, topY, bottomX, bottomY
@@ -329,22 +321,27 @@ function Draw (self, vOffset, hOffset)
329321
check (WindowImageFromWindow ( self.parent.windowName, self.parent.windowName .. "glass", self.parent.windowName .. "glass") )
330322
check (WindowBlendImage ( self.parent.windowName, self.parent.windowName .. "glass", dtX, dtY, dbX, dbY, 21, .45) )
331323
elseif CheckStyle(self, barStyles.raised + barStyles.raisedCap + barStyles.sunken) then -- 3D frame rectangle
332-
check (WindowRectOp (self.parent.windowName, 5, topX , topY , bottomX, bottomY, bezel[not CheckStyle(self, barStyles.sunken + barStyles.glass)] ,1+2+4+8 + 0x1000) )
324+
check (WindowRectOp (self.parent.windowName, 5, topX , topY , bottomX, bottomY, bezel[not CheckStyle(self, barStyles.sunken + barStyles.glass)] ,0x100F) )
333325
end end
334326
if bit.band( self.barStyle , 31 ) ~= 0 then -- frame rectangle on border
335327
local pen = {[true]=1,[false]=5}
336328
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) )
337329
end end
338-
vOffset = vOffset
339-
PrintText (self, vOffset, hOffset)
340-
return vOffset + self.cellHeight + self.padding
330+
PrintText (self, self.cellTop, self.cellLeft)
331+
if type(self.button) == 'table' then
332+
WindowAddHotspot(self.windowName, self.id, self.cellLeft, self.cellTop, self.cellLeft + self.cellWidth, self.cellTop + self.cellHeight,
333+
self.button.mouseOver or "", self.button.cancelMouseOver or "", self.button.mouseDown or "", self.button.cancelMouseDown or "",
334+
self.button.mouseUp or "", self.button.tooltipText or "", self.button.cursor or 0, 0 )
335+
336+
end
337+
return self.cellTop + self.cellHeight + self.padding
341338
end
342339

343340
--[=[ Internal Function that calculates different shades of colors ]=]--
344341
function DoFade(self)
345342
--TraceOut (string.format("%s: Window %s Bar %i", "DoFade", self.windowName, self.id))
346343
local color
347-
if not self.shades then
344+
if self.shades == nil or (self.Bar.shades and self.goodColour ~= self.Bar.goodColour and self.badColour ~= self.Bar.badColour) then
348345
self.shades = CalcShades(self, math.ceil(100 - self.threshold)/5)
349346
end
350347
if self.value >= self.threshold then
@@ -355,6 +352,18 @@ function DoFade(self)
355352
return color
356353
end
357354

355+
356+
--[=[ See :Doc( "Fade" ) --]=]--
357+
function Bar:Fade (bool)
358+
assert(bool and type(bool)=="boolean", "Boolean expected. Got " .. tostring( bool ) .. "(" .. type(bool) .. ")")
359+
self.fade = bool
360+
self.shades = nil
361+
if bool then
362+
DoFade(self)
363+
end
364+
end
365+
366+
358367
--[=[ See :Doc( "TextColour" ) --]=]--
359368
function Bar:TextColour (x)
360369
--TraceOut (string.format("%s: Window %s Bar %i", "TextColour", self.windowName, self.id))
@@ -539,6 +548,19 @@ function _M:New (winName)
539548
return q
540549
end
541550

551+
--[=[ See :Doc( "BackgroundColour" ) --]=]--
552+
function _M:BackgroundColour (col)
553+
assert (col, "Nil passed. specify a colour.")
554+
local n = tonumber(col) or ColourNameToRGB(col)
555+
assert(n and n~= -1,'Bad value passed. Acceptable examples: "red", 255, 0x0000ff, "#FF0000" - Got '.. tostring(x) .. '('.. type(x) ..')')
556+
self.backgroundColour = n
557+
self.matteHilight, self.matteShadow = self.backgroundColour,self.backgroundColour
558+
for i = 1,10 do
559+
self.matteHilight = AdjustColour(self.matteHilight,2)
560+
self.matteShadow = AdjustColour(self.matteShadow,3)
561+
end
562+
end
563+
542564
--[=[ See :Doc( "Rows" ) --]=]--
543565
function _M:Rows(num)
544566
assert(type(num)=="number" and num > 0, "How many rows? Need a positive number. Got " .. type(num) )
@@ -606,20 +628,20 @@ function _M:RemoveBar(index)
606628
end end
607629

608630
--[=[ See :Doc( "Update" ) --]=]--
609-
function _M:Update ()
631+
function _M:Update (force)
610632
--TraceOut (string.format("%s: Window %s", "Update", self.windowName))
611633
assert(self ~= _M , "Pass a table called from ".. _NAME .. ":New(), not ".. _NAME .. " itself.")
612634
--Note: It is possible to pass any table instance into this. i.e. foo, foo.Bar, foo.Bars[i]
613635
--It may be bad style, but it intentionally will work. foo.Bars[i] still updates the entire window, not just its region.
614-
if os.time() > (self.lastUpdated or 0) then
636+
if os.time() > (self.lastUpdated or 0) or force then
615637
local MiniWindow = self.parent or self
616638
check (WindowCreate (self.windowName, 0, 0, self.windowWidth, self.windowHeight, self.windowPosition, self.windowFlags, GetInfo(278)) )
617639
check (WindowRectOp (self.windowName, 2, 2, 2, -2, -2, self.backgroundColour) ) -- "erase" miniwindw
618-
local vertical,horizontal, curRow, curCol, t = 4, 0, 1, 1
640+
local vertical,horizontal, curRow, curCol, t = 6, 0, 1, 1
619641
for _, curBar in ipairs(self.Bars) do
620642
local finishY = vertical + curBar.cellHeight + curBar.padding
621643
if curRow > self.rows or finishY > self.windowHeight then
622-
vertical = 4
644+
vertical = 6
623645
curCol = curCol + 1
624646
curRow = 1
625647
if curCol > self.columns then --Maybe Fonts are distorting the grid
@@ -632,6 +654,7 @@ function _M:Update ()
632654
curRow=curRow+1
633655
end
634656
check (WindowRectOp (self.windowName, 5, 0, 1, -1, -2, 10, 15) ) -- 3D border effect on canvas
657+
WindowRectOp (self.windowName, 2, self.windowWidth - 2 , 0, 0, 0, GetInfo(278), nil)
635658
WindowShow (self.windowName, true)
636659
self.lastUpdated = os.time()
637660
return true
@@ -675,7 +698,7 @@ function _M:ResizeOutput()
675698
if self.displaceOutput then
676699
if self.windowPosition == 9 or self.windowPosition == 10 then
677700
if sum(9,10) == 1 then
678-
height = -self.windowHeight
701+
height = -self.windowHeight - 8
679702
else
680703
height = -math.max(math.abs(height), self.windowHeight)
681704
end
@@ -833,7 +856,6 @@ function _M:Font(...)
833856
self.fontName, self.fontSize = name, fontParams[1]
834857
if self == MiniWindow then
835858
MiniWindow.windowHeight = _M.windowHeight
836-
tp = require "tprint" tp(fontParams)
837859
check(WindowFont(MiniWindow.windowName, unpack(fontParams) ) )
838860
MiniWindow.Bar.cellHeight = WindowFontInfo (MiniWindow.windowName, MiniWindow.fontID, 1) + MiniWindow.Bar.cellPadding
839861
else
@@ -963,7 +985,7 @@ function CalcShades(self, shades) -- the number of shades including start and en
963985
step.g = (g1-g2)/shades
964986
step.b = (b1-b2)/shades
965987
for i = 0, shades do
966-
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)
988+
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)
967989
end
968990
Cs[#Cs] = self.badColour
969991
return Cs, step, step.r, step.g, step.b
@@ -1549,6 +1571,90 @@ Assuming:
15491571
MW,
15501572
then InfoBox
15511573
]],
1574+
1575+
["button"] =[[
1576+
Applies To: Bar
1577+
Protoype: bar.button = {mouseUp = "funcname", ...}
1578+
1579+
1580+
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).
1581+
Missing keys are fine. (i.e. {mouseUp="f"} is OK. {mouseUp="f", mouseDown="", cancelMouseDown=""... is not necessary.)
1582+
1583+
Expected keys are named:
1584+
mouseUp
1585+
mouseDown
1586+
cancelMouseDown
1587+
tooltipText
1588+
mouseOver
1589+
cancelMouseOver
1590+
cursor
1591+
1592+
Your functions should be structured as:
1593+
function myClickFunction (flags, strBarsIndex)
1594+
local id = tonumber(strBarsIndex) -- because tbl["1"] is a different key than tbl[1]
1595+
...
1596+
MW.Bars[id].caption = "Clicked"
1597+
end
1598+
]],
1599+
1600+
["cellTop"] =[[
1601+
Applies To: Bar
1602+
Protoype: x = bar.cellTop
1603+
1604+
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.
1605+
]],
1606+
1607+
["cellLeft"] =[[
1608+
Applies To: Bar
1609+
Protoype: x = bar.cellLeft
1610+
1611+
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.
1612+
]],
1613+
1614+
["Fade"] =[[
1615+
Applies To: Bar
1616+
Protoype: bar:Fade(bool)
1617+
1618+
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.
1619+
1620+
Try the following:
1621+
for x = 100,30,-10 do
1622+
local foo = MW:AddBar("", x, "green", "red", false, MW.barStyles.glass + MW.barStyles.gradientScale)
1623+
foo:Fade(true)
1624+
foo.badColour = colour_names.dodgerblue
1625+
end
1626+
1627+
It's a bug, but it looks cool. Also this is why using the functions to set values is recommended!
1628+
]],
1629+
1630+
["cellWidth"] =[[
1631+
Applies To: Bar
1632+
Protoype: x = bar.cellWidth
1633+
1634+
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.
1635+
]], --']]
1636+
1637+
["*AddYourOwn"] =[[
1638+
Applies To: ALL
1639+
Protoype: N/A
1640+
1641+
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.
1642+
pairs() is used to copy InfoBox.Bar to MW.Bar
1643+
ipairs() is used on the MW.Bar table to find the functions for the default parameters for AddBar.
1644+
ipairs() is used on the MW.Bars table to draw the bars.
1645+
1646+
Other than avoiding numerical indices in the 2 Bar(s) tables, it should be safe to add to a table as you see fit.
1647+
]],
1648+
1649+
--[=[
1650+
[""] =[[
1651+
Applies To:
1652+
Protoype:
1653+
1654+
1655+
]],
1656+
1657+
--]=]-- ']]
15521658
}
15531659

15541660
function Doc (self, topic)

0 commit comments

Comments
 (0)