Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ------------------------------------
- --- DEMO script ---
- --- ETK By Jim Bauwens ---
- --- Additions by Adrien Bertrand ---
- ------------------------------------
- --- Real demo code : line 1234 ---
- ------------------------------------
- ------------------------------------------------------------------
- -- Overall Global Variables --
- ------------------------------------------------------------------
- kXSize = 1 -- will get changed
- kYSize = 1 -- will get changed
- function math.round(num, idp)
- return tonumber(string.format("%." .. (idp or 0) .. "f", num))
- end
- --
- -- Uses BetterLuaAPI : https://github.com/adriweb/BetterLuaAPI-for-TI-Nspire
- --
- a_acute = string.uchar(225)
- a_circ = string.uchar(226)
- a_tilde = string.uchar(227)
- a_diaer = string.uchar(228)
- a_ring = string.uchar(229)
- e_acute = string.uchar(233)
- e_grave = string.uchar(232)
- o_acute = string.uchar(243)
- o_circ = string.uchar(244)
- l_alpha = string.uchar(945)
- l_beta = string.uchar(946)
- l_omega = string.uchar(2126)
- sup_plus = string.uchar(8314)
- sup_minus = string.uchar(8315)
- right_arrow = string.uchar(8594)
- Color = {
- ["black"] = { 0, 0, 0 },
- ["red"] = { 255, 0, 0 },
- ["green"] = { 0, 255, 0 },
- ["blue"] = { 0, 0, 255 },
- ["white"] = { 255, 255, 255 },
- ["brown"] = { 165, 42, 42 },
- ["cyan"] = { 0, 255, 255 },
- ["darkblue"] = { 0, 0, 139 },
- ["darkred"] = { 139, 0, 0 },
- ["gold"] = { 255, 215, 0 },
- ["gray"] = { 127, 127, 127 },
- ["grey"] = { 127, 127, 127 },
- ["lightblue"] = { 173, 216, 230 },
- ["lightgreen"] = { 144, 238, 144 },
- ["magenta"] = { 255, 0, 255 },
- ["maroon"] = { 128, 0, 0 },
- ["navyblue"] = { 159, 175, 223 },
- ["orange"] = { 255, 165, 0 },
- ["pink"] = { 255, 192, 203 },
- ["purple"] = { 128, 0, 128 },
- ["royalblue"] = { 65, 105, 225 },
- ["silver"] = { 192, 192, 192 },
- ["violet"] = { 238, 130, 238 },
- ["yellow"] = { 255, 255, 0 }
- }
- Color.mt = { __index = function() return { 0, 0, 0 } end }
- setmetatable(Color, Color.mt)
- function copyTable(t)
- local t2 = {}
- for k, v in pairs(t) do
- t2[k] = v
- end
- return t2
- end
- function deepcopy(t) -- This function recursively copies a table's contents, and ensures that metatables are preserved. That is, it will correctly clone a pure Lua object.
- if type(t) ~= 'table' then return t end
- local mt = getmetatable(t)
- local res = {}
- for k, v in pairs(t) do
- if type(v) == 'table' then
- v = deepcopy(v)
- end
- res[k] = v
- end
- setmetatable(res, mt)
- return res
- end
- -- from http://snippets.luacode.org/snippets/Deep_copy_of_a_Lua_Table_2
- function utf8(nbr)
- return string.uchar(nbr)
- end
- function test(arg)
- return arg and 1 or 0
- end
- function screenRefresh()
- return platform.window:invalidate()
- end
- function pww()
- return platform.window:width()
- end
- function pwh()
- return platform.window:height()
- end
- function drawPoint(gc, x, y)
- gc:fillRect(x, y, 1, 1)
- end
- function drawCircle(gc, x, y, diam)
- gc:drawArc(x, y, diam, diam, 0, 360)
- end
- function fillCircle(gc, x, y, diam)
- gc:fillArc(x, y, diam, diam, 0, 360)
- end
- function drawCenteredString(gc, str)
- gc:drawString(str, .5 * (pww() - gc:getStringWidth(str)), .5 * pwh(), "middle")
- end
- function drawXCenteredString(gc, str, y)
- gc:drawString(str, .5 * (pww() - gc:getStringWidth(str)), y, "top")
- end
- function setColor(gc, theColor)
- if type(theColor) == "string" then
- theColor = string.lower(theColor)
- if type(Color[theColor]) == "table" then gc:setColorRGB(unpack(Color[theColor])) end
- elseif type(theColor) == "table" then
- gc:setColorRGB(unpack(theColor))
- end
- end
- function verticalBar(gc, x)
- gc:fillRect(x, 0, 1, pwh())
- end
- function horizontalBar(gc, y)
- gc:fillRect(0, y, pww(), 1)
- end
- function nativeBar(gc, screen, y)
- gc:setColorRGB(128,128,128)
- gc:fillRect(screen.x+5, screen.y+y, screen.w-10, 2)
- end
- function drawSquare(gc, x, y, l)
- gc:drawPolyLine({ (x - l / 2), (y - l / 2), (x + l / 2), (y - l / 2), (x + l / 2), (y + l / 2), (x - l / 2), (y + l / 2), (x - l / 2), (y - l / 2) })
- end
- function drawRoundRect(gc, x, y, wd, ht, rd) -- wd = width, ht = height, rd = radius of the rounded corner
- x = x - wd / 2 -- let the center of the square be the origin (x coord)
- y = y - ht / 2 -- same for y coord
- if rd > ht / 2 then rd = ht / 2 end -- avoid drawing cool but unexpected shapes. This will draw a circle (max rd)
- gc:drawLine(x + rd, y, x + wd - (rd), y);
- gc:drawArc(x + wd - (rd * 2), y + ht - (rd * 2), rd * 2, rd * 2, 270, 90);
- gc:drawLine(x + wd, y + rd, x + wd, y + ht - (rd));
- gc:drawArc(x + wd - (rd * 2), y, rd * 2, rd * 2, 0, 90);
- gc:drawLine(x + wd - (rd), y + ht, x + rd, y + ht);
- gc:drawArc(x, y, rd * 2, rd * 2, 90, 90);
- gc:drawLine(x, y + ht - (rd), x, y + rd);
- gc:drawArc(x, y + ht - (rd * 2), rd * 2, rd * 2, 180, 90);
- end
- function fillRoundRect(gc, x, y, wd, ht, radius) -- wd = width and ht = height -- renders badly when transparency (alpha) is not at maximum >< will re-code later
- if radius > ht / 2 then radius = ht / 2 end -- avoid drawing cool but unexpected shapes. This will draw a circle (max radius)
- gc:fillPolygon({ (x - wd / 2), (y - ht / 2 + radius), (x + wd / 2), (y - ht / 2 + radius), (x + wd / 2), (y + ht / 2 - radius), (x - wd / 2), (y + ht / 2 - radius), (x - wd / 2), (y - ht / 2 + radius) })
- gc:fillPolygon({ (x - wd / 2 - radius + 1), (y - ht / 2), (x + wd / 2 - radius + 1), (y - ht / 2), (x + wd / 2 - radius + 1), (y + ht / 2), (x - wd / 2 + radius), (y + ht / 2), (x - wd / 2 + radius), (y - ht / 2) })
- x = x - wd / 2 -- let the center of the square be the origin (x coord)
- y = y - ht / 2 -- same
- gc:fillArc(x + wd - (radius * 2), y + ht - (radius * 2), radius * 2, radius * 2, 1, -91);
- gc:fillArc(x + wd - (radius * 2), y, radius * 2, radius * 2, -2, 91);
- gc:fillArc(x, y, radius * 2, radius * 2, 85, 95);
- gc:fillArc(x, y + ht - (radius * 2), radius * 2, radius * 2, 180, 95);
- end
- function drawLinearGradient(gc, color1, color2)
- -- syntax would be : color1 and color2 as {r,g,b}.
- -- don't really know how to do that. probably converting to hue/saturation/light mode and change the hue.
- -- todo with unpack(color1) and unpack(color2)
- end
- function bigText(gc)
- gc:setFont("serif", "b", 18)
- end
- function normalText(gc)
- gc:setFont("sansserif", "r", 12)
- end
- local tstart = timer.start
- function timer.start(ms)
- if not timer.isRunning then
- tstart(ms)
- end
- timer.isRunning = true
- end
- local tstop = timer.stop
- function timer.stop()
- timer.isRunning = false
- tstop()
- end
- stdout = print
- function pprint(...)
- stdout(...)
- local out = ""
- for _,v in ipairs({...}) do
- out = out .. (_==1 and "" or " ") .. tostring(v)
- end
- var.store("print", out)
- end
- function Pr(n, d, s, ex)
- local nc = tonumber(n)
- if nc and nc<math.abs(nc) then
- return s-ex-(type(n)== "number" and math.abs(n) or (.01*s*math.abs(nc)))
- else
- return (type(n)=="number" and n or (type(n)=="string" and .01*s*nc or d))
- end
- end
- -- Apply an extension on a class, and return our new frankenstein
- function addExtension(oldclass, extension)
- local newclass = class(oldclass)
- for key, data in pairs(extension) do
- newclass[key] = data
- end
- return newclass
- end
- clipRectData = {}
- function gc_clipRect(gc, what, x, y, w, h)
- if what == "set" and clipRectData.current then
- clipRectData.old = clipRectData.current
- elseif what == "subset" and clipRectData.current then
- clipRectData.old = clipRectData.current
- x = clipRectData.old.x<x and x or clipRectData.old.x
- y = clipRectData.old.y<y and y or clipRectData.old.y
- h = clipRectData.old.y+clipRectData.old.h > y+h and h or clipRectData.old.y+clipRectData.old.h-y
- w = clipRectData.old.x+clipRectData.old.w > x+w and w or clipRectData.old.x+clipRectData.old.w-x
- what = "set"
- elseif what == "subset" then
- what = "set"
- elseif what == "restore" and clipRectData.old then
- --gc:clipRect("reset")
- what = "set"
- x = clipRectData.old.x
- y = clipRectData.old.y
- h = clipRectData.old.h
- w = clipRectData.old.w
- elseif what == "restore" then
- what = "reset"
- end
- gc:clipRect(what, x, y, w, h)
- if x and y and w and h then clipRectData.current = {x=x,y=y,w=w,h=h} end
- end
- ------------------------------------------------------------------
- -- Screen Class --
- ------------------------------------------------------------------
- Screen = class()
- Screens = {}
- function push_screen(screen, ...)
- current_screen():screenLoseFocus()
- table.insert(Screens, screen)
- platform.window:invalidate()
- current_screen():pushed(...)
- end
- function only_screen(screen, ...)
- current_screen():screenLoseFocus()
- Screens = {screen}
- platform.window:invalidate()
- screen:pushed(...)
- end
- function remove_screen(...)
- platform.window:invalidate()
- current_screen():removed(...)
- res=table.remove(Screens)
- current_screen():screenGetFocus()
- return res
- end
- function current_screen()
- return Screens[#Screens] or DummyScreen
- end
- function Screen:init(xx,yy,ww,hh)
- self.yy = yy
- self.xx = xx
- self.hh = hh
- self.ww = ww
- self:ext()
- self:size(0)
- end
- function Screen:ext()
- end
- function Screen:size()
- local screenH = platform.window:height()
- local screenW = platform.window:width()
- if screenH == 0 then screenH=212 end
- if screenW == 0 then screenW=318 end
- self.x = math.floor(Pr(self.xx, 0, screenW, 0)+.5)
- self.y = math.floor(Pr(self.yy, 0, screenH, 0)+.5)
- self.w = math.floor(Pr(self.ww, screenW, screenW, 0)+.5)
- self.h = math.floor(Pr(self.hh, screenH, screenH, 0)+.5)
- end
- function Screen:pushed() end
- function Screen:removed() end
- function Screen:screenLoseFocus() end
- function Screen:screenGetFocus() end
- function Screen:draw(gc)
- self:size()
- self:paint(gc)
- end
- function Screen:paint(gc) end
- function Screen:invalidate()
- platform.window:invalidate(self.x ,self.y , self.w, self.h)
- end
- function Screen:arrowKey(arrw) end
- function Screen:enterKey() end
- function Screen:backspaceKey() end
- function Screen:escapeKey() end
- function Screen:tabKey() end
- function Screen:backtabKey() end
- function Screen:clearKey() end
- function Screen:charIn(ch) end
- function Screen:timer() end
- function Screen:mouseDown(x,y) end
- function Screen:mouseUp(x,y) end
- function Screen:mouseMove(x,y) end
- function Screen:contextMenu() end
- function Screen:resize(x,y) end
- function Screen:grabDown(x,y) end
- function Screen:appended() end
- function Screen:destroy()
- self = nil
- end
- ------------------------------------------------------------------
- -- WidgetManager Extension --
- ------------------------------------------------------------------
- WidgetManager = {}
- function WidgetManager:ext()
- self.widgets = {}
- self.focus = 0
- end
- function WidgetManager:appendWidget(widget, xx, yy)
- widget.xx = xx
- widget.yy = yy
- widget.parent = self
- widget:size()
- widget.pid = #self.widgets
- table.insert(self.widgets, widget)
- widget:appended(self)
- return self
- end
- function WidgetManager:removeWidget(widget)
- --table.remove(self.widgets, widget.pid)
- --TODO !
- end
- function WidgetManager:cleanWidgets()
- self.widgets = {}
- self.focus = 0
- end
- function WidgetManager:getWidget()
- return self.widgets[self.focus]
- end
- function WidgetManager:drawWidgets(gc)
- for _, widget in pairs(self.widgets) do
- widget:size()
- widget:draw(gc)
- gc:setColorRGB(0,0,0)
- end
- end
- function WidgetManager:postPaint(gc)
- end
- function WidgetManager:draw(gc)
- self:size()
- self:paint(gc)
- self:drawWidgets(gc)
- self:postPaint(gc)
- end
- function WidgetManager:loop(n) end
- function WidgetManager:stealFocus(n)
- local oldfocus=self.focus
- if oldfocus~=0 then
- local veto = self:getWidget():loseFocus(n)
- if veto == -1 then
- return -1, oldfocus
- end
- self:getWidget().hasFocus = false
- self.focus = 0
- end
- return 0, oldfocus
- end
- function WidgetManager:focusChange() end
- function WidgetManager:switchFocus(n, b)
- if n~=0 and #self.widgets>0 then
- local veto, focus = self:stealFocus(n)
- if veto == -1 then
- return -1
- end
- local looped
- self.focus = focus + n
- if self.focus>#self.widgets then
- self.focus = 1
- looped = true
- elseif self.focus<1 then
- self.focus = #self.widgets
- looped = true
- end
- if looped and self.noloop and not b then
- self.focus = focus
- self:loop(n)
- else
- self:getWidget().hasFocus = true
- self:getWidget():getFocus(n)
- end
- end
- self:focusChange()
- end
- function WidgetManager:arrowKey(arrow)
- if self.focus~=0 then
- self:getWidget():arrowKey(arrow)
- end
- self:invalidate()
- end
- function WidgetManager:enterKey()
- if self.focus~=0 then
- self:getWidget():enterKey()
- end
- self:invalidate()
- end
- function WidgetManager:backspaceKey()
- if self.focus~=0 then
- self:getWidget():backspaceKey()
- end
- self:invalidate()
- end
- function WidgetManager:escapeKey()
- if self.focus~=0 then
- self:getWidget():escapeKey()
- end
- self:invalidate()
- end
- function WidgetManager:clearKey()
- if self.focus~=0 then
- self:getWidget():clearKey()
- end
- self:invalidate()
- end
- function WidgetManager:tabKey()
- self:switchFocus(1)
- self:invalidate()
- end
- function WidgetManager:backtabKey()
- self:switchFocus(-1)
- self:invalidate()
- end
- function WidgetManager:charIn(char)
- if self.focus~=0 then
- self:getWidget():charIn(char)
- end
- self:invalidate()
- end
- function WidgetManager:getWidgetIn(x, y)
- for n, widget in pairs(self.widgets) do
- local wox = widget.ox or 0
- local woy = widget.oy or 0
- if x>=widget.x-wox and y>=widget.y-wox and x<widget.x+widget.w-wox and y<widget.y+widget.h-woy then
- return n, widget
- end
- end
- end
- function WidgetManager:mouseDown(x, y)
- local n, widget = self:getWidgetIn(x, y)
- if n then
- if self.focus~=0 and self.focus~=n then self:getWidget().hasFocus = false self:getWidget():loseFocus() end
- self.focus = n
- widget.hasFocus = true
- widget:getFocus()
- widget:mouseDown(x, y)
- self:focusChange()
- else
- if self.focus~=0 then self:getWidget().hasFocus = false self:getWidget():loseFocus() end
- self.focus = 0
- end
- end
- function WidgetManager:mouseUp(x, y)
- if self.focus~=0 then
- self:getWidget():mouseUp(x, y)
- end
- self:invalidate()
- end
- function WidgetManager:mouseMove(x, y)
- if self.focus~=0 then
- self:getWidget():mouseMove(x, y)
- end
- end
- --------------------------
- -- Our new frankenstein --
- --------------------------
- WScreen = addExtension(Screen, WidgetManager)
- --Dialog screen
- Dialog = class(WScreen)
- function Dialog:init(title,xx,yy,ww,hh)
- self.yy = yy
- self.xx = xx
- self.hh = hh
- self.ww = ww
- self.title = title
- self:size()
- self.widgets = {}
- self.focus = 0
- end
- function Dialog:paint(gc)
- self.xx = (pww()-self.w)/2
- self.yy = (pwh()-self.h)/2
- self.x, self.y = self.xx, self.yy
- gc:setFont("sansserif","r",10)
- gc:setColorRGB(224,224,224)
- gc:fillRect(self.x, self.y, self.w, self.h)
- for i=1, 14,2 do
- gc:setColorRGB(32+i*3, 32+i*4, 32+i*3)
- gc:fillRect(self.x, self.y+i, self.w,2)
- end
- gc:setColorRGB(32+16*3, 32+16*4, 32+16*3)
- gc:fillRect(self.x, self.y+15, self.w, 10)
- gc:setColorRGB(128,128,128)
- gc:drawRect(self.x, self.y, self.w, self.h)
- gc:drawRect(self.x-1, self.y-1, self.w+2, self.h+2)
- gc:setColorRGB(96,100,96)
- gc:fillRect(self.x+self.w+1, self.y, 1, self.h+2)
- gc:fillRect(self.x, self.y+self.h+2, self.w+3, 1)
- gc:setColorRGB(104,108,104)
- gc:fillRect(self.x+self.w+2, self.y+1, 1, self.h+2)
- gc:fillRect(self.x+1, self.y+self.h+3, self.w+3, 1)
- gc:fillRect(self.x+self.w+3, self.y+2, 1, self.h+2)
- gc:fillRect(self.x+2, self.y+self.h+4, self.w+2, 1)
- gc:setColorRGB(255,255,255)
- gc:drawString(self.title, self.x + 4, self.y+2, "top")
- self:postPaint(gc)
- end
- function Dialog:postPaint() end
- ---
- -- The dummy screen
- ---
- DummyScreen = Screen()
- function uCol(col)
- return col[1] or 0, col[2] or 0, col[3] or 0
- end
- function textLim(gc, text, max)
- local ttext, out = "",""
- local width = gc:getStringWidth(text)
- if width<max then
- return text, width
- else
- for i=1, #text do
- ttext = text:usub(1, i)
- if gc:getStringWidth(ttext .. "..")>max then
- break
- end
- out = ttext
- end
- return out .. "..", gc:getStringWidth(out .. "..")
- end
- end
- ------------------------------------------------------------------
- -- Widget Class --
- ------------------------------------------------------------------
- Widget = class(Screen)
- function Widget:init()
- self.dw = 10
- self.dh = 10
- self:ext()
- end
- function Widget:setSize(w, h)
- self.ww = w or self.ww
- self.hh = h or self.hh
- end
- function Widget:setPos(x, y)
- self.xx = x or self.xx
- self.yy = y or self.yy
- end
- function Widget:size(n)
- if n then return end
- self.w = math.floor(Pr(self.ww, self.dw, self.parent.w, 0)+.5)
- self.h = math.floor(Pr(self.hh, self.dh, self.parent.h, 0)+.5)
- self.rx = math.floor(Pr(self.xx, 0, self.parent.w, self.w)+.5)
- self.ry = math.floor(Pr(self.yy, 0, self.parent.h, self.h)+.5)
- self.x = self.parent.x + self.rx
- self.y = self.parent.y + self.ry
- end
- function Widget:giveFocus()
- if self.parent.focus~=0 then
- local veto = self.parent:stealFocus()
- if veto == -1 then
- return -1
- end
- end
- self.hasFocus = true
- self.parent.focus = self.pid
- self:getFocus()
- end
- function Widget:getFocus() end
- function Widget:loseFocus() end
- function Widget:enterKey()
- self.parent:switchFocus(1)
- end
- function Widget:arrowKey(arrow)
- if arrow=="up" then
- self.parent:switchFocus(self.focusUp or -1)
- elseif arrow=="down" then
- self.parent:switchFocus(self.focusDown or 1)
- elseif arrow=="left" then
- self.parent:switchFocus(self.focusLeft or -1)
- elseif arrow=="right" then
- self.parent:switchFocus(self.focusRight or 1)
- end
- end
- WWidget = addExtension(Widget, WidgetManager)
- ------------------------------------------------------------------
- -- Sample Widget --
- ------------------------------------------------------------------
- -- First, create a new class based on Widget
- box = class(Widget)
- -- Init. You should define self.dh and self.dw, in case the user doesn't supply correct width/height values.
- -- self.ww and self.hh can be a number or a string. If it's a number, the width will be that amount of pixels.
- -- If it's a string, it will be interpreted as % of the parent screen size.
- -- These values will be used to calculate self.w and self.h (don't write to this, it will overwritten everytime the widget get's painted)
- -- self.xx and self.yy will be set when appending the widget to a screen. This value support the same % method (in a string)
- -- They will be used to calculate self.x and self.h
- function box:init(ww,hh,t)
- self.dh = 10
- self.dw = 10
- self.ww = ww
- self.hh = hh
- self.t = t
- end
- -- Paint. Here you can paint your widget stuff
- -- Variable you can use:
- -- self.x, self.y : numbers, x and y coordinates of the widget relative to screen. So it's the actual pixel position on the screen.
- -- self.w, self.h : numbers, w and h of widget
- -- many others
- function box:paint(gc)
- gc:setColorRGB(0,0,0)
- -- Do I have focus?
- if self.hasFocus then
- -- Yes, draw a filled black square
- gc:fillRect(self.x, self.y, self.w, self.h)
- else
- -- No, draw only the outline
- gc:drawRect(self.x, self.y, self.w, self.h)
- end
- gc:setColorRGB(128,128,128)
- if self.t then
- gc:drawString(self.t,self.x+2,self.y+2,"top")
- end
- end
- ------------------------------------------------------------------
- -- Input Widget --
- ------------------------------------------------------------------
- sInput = class(Widget)
- function sInput:init(callback)
- self.dw = 25
- self.dh = 20
- self.value = ""
- self.bgcolor = { 255, 255, 255 }
- self.disabledcolor = { 128, 128, 128 }
- self.textcolor = { 0, 0, 0 }
- self.font = { "sansserif", "r", 10 }
- self.disabled = false
- --self.capsOnly = true -- this activity only...
- --self.number = true -- this activity
- self.centeredText = true
- self.callback = callback
- end
- function sInput:paint(gc)
- self.gc = gc
- local x = self.x
- local y = self.y
- gc:setFont(uCol(self.font))
- gc:setColorRGB(uCol(self.bgcolor))
- gc:fillRect(x + 2, y + 2, self.w - 3, self.h - 3)
- gc:setColorRGB(0, 0, 0)
- if not self.hasFocus and not self.disabled then
- gc:setPen("thin", "dashed")
- gc:drawRect(x, y, self.w, self.h)
- gc:setPen("thin", "smooth")
- end
- if self.showBorder then
- gc:drawRect(x, y, self.w, self.h)
- end
- if self.hasFocus and not self.disabled then
- gc:drawRect(x, y, self.w, self.h)
- end
- if self.hasFocus and not self.disabled then
- gc:drawRect(x-1, y-1, self.w+2, self.h+2)
- end
- local text = self.value
- local p = 0
- --gc_clipRect(gc, "subset", x, y, self.w, self.h)
- --[[
- while true do
- if p==#self.value then break end
- p = p + 1
- text = self.value:sub(-p, -p) .. text
- if gc:getStringWidth(text) > (self.w - 8) then
- text = text:sub(2,-1)
- break
- end
- end
- --]]
- if --[[self.disabled or]] self.value == "" then
- gc:setColorRGB(uCol(self.disabledcolor))
- end
- if self.value == "" then
- text = self.placeholder or ""
- gc:setFont("serif", "i", 12)
- --self.usingPlaceholder = true
- end
- gc:setColorRGB(unpack(self.textcolor))
- local strwidth = gc:getStringWidth(text)
- if strwidth < self.w - 4 or not self.hasFocus then
- gc:drawString(text, self.centeredText and 0.5 * ((2 * self.x + self.w) - gc:getStringWidth(text)) or self.x + 4, y - 1, "top")
- else
- gc:drawString(text, x - 4 + self.w - strwidth, y - 1, "top")
- end
- if self.hasFocus and self.value ~= "" and not self.disabled then -- draw cursor
- -- gc:fillRect(self.x+(text==self.value and strwidth+2 or self.w-4)+(self.centeredText and 0.15*((2*self.x+self.w)-3*gc:getStringWidth(self.value)) or 0), self.y, 1, self.h)
- end
- gc_clipRect(gc, "restore")
- end
- function sInput:charIn(char)
- if self.disabled or (self.number and not tonumber(self.value .. char)) then --or char~="," then
- return
- end
- --char = (char == ",") and "." or char
- self.value = self.value .. (self.capsOnly and char:upper() or char)
- end
- function sInput:backspaceKey()
- if not self.disabled then
- self.value = self.value:usub(1, -2)
- end
- end
- function sInput:enterKey()
- if self.callback then self.callback() end
- end
- function sInput:enable()
- self.disabled = false
- end
- function sInput:disable()
- self.disabled = true
- end
- ------------------------------------------------------------------
- -- Label Widget --
- ------------------------------------------------------------------
- sLabel = class(Widget)
- function sLabel:init(text, options, widget)
- self.widget = widget
- self.text = text
- self.ww = 30
- self.options = options or {}
- self.font = self.options.font or "sansserif"
- self.style = self.options.style or "r"
- self.textSize = self.options.size or 10
- self.decoration = self.options.decoration
- self.hh = 20
- self.lim = false
- self.color = { 0, 0, 0 }
- self.color = self.options.color or self.color
- self.font = { self.font, self.style, self.textSize }
- self.p = "top"
- end
- function sLabel:paint(gc)
- gc:setFont(uCol(self.font))
- --gc:setColorRGB(255, 255, 255)
- --gc:fillRect(self.x, self.y, 3*self.w, self.h)
- gc:setColorRGB(uCol(self.color))
- local text = ""
- local ttext
- if self.lim then
- text, self.dw = textLim(gc, self.text, self.w)
- else
- text = self.text
- end
- self.textW, self.textH = gc:getStringWidth(text), gc:getStringHeight(text)
- for i, line in ipairs(tostring(text):split("\n")) do
- gc:drawString(line, self.x, self.y + (i-1)*self.textH, self.p, "top")
- end
- if self.decoration == "underline" then
- gc:drawLine(self.x, self.y+self.textH, self.x+self.textW, self.y+self.textH)
- end
- end
- function sLabel:getFocus(n)
- --[[if n then
- n = n < 0 and -1 or (n > 0 and 1 or 0)
- end
- if self.widget and not n then
- self.widget:giveFocus()
- elseif n then
- self.parent:switchFocus(n)
- end]] --
- --return false
- self.parent:switchFocus(1)
- end
- ------------------------------------------------------------------
- -- Button Widget --
- ------------------------------------------------------------------
- sButton = class(Widget)
- function sButton:init(text, action)
- self.text = text
- self.action = action
- self.dh = 27
- self.dw = 48
- self.bgColor = {248,232,170}
- self.bordercolor = {136,136,136}
- self.font = {"sansserif", "r", 10}
- end
- function sButton:paint(gc)
- gc:setFont(uCol(self.font))
- self.ww = gc:getStringWidth(self.text)+8
- self:size()
- if self.pushed and self.forcePushed and not self.disabled then
- self.y = self.y + 2
- end
- if self.disabled then
- self.bgColor = {250,245,200}
- end
- gc:setColorRGB(unpack(self.bgColor))
- gc:fillRect(self.x+2, self.y+2, self.w-4, self.h-4)
- gc:setColorRGB(0,0,0)
- if self.disabled then gc:setColorRGB(70,70,70) end
- gc:drawString(self.text, self.x+4, self.y+4, "top")
- gc:setColorRGB(uCol(self.bordercolor))
- gc:fillRect(self.x + 2, self.y, self.w-4, 2)
- gc:fillRect(self.x + 2, self.y+self.h-2, self.w-4, 2)
- gc:fillRect(self.x, self.y+2, 1, self.h-4)
- gc:fillRect(self.x+1, self.y+1, 1, self.h-2)
- gc:fillRect(self.x+self.w-1, self.y+2, 1, self.h-4)
- gc:fillRect(self.x+self.w-2, self.y+1, 1, self.h-2)
- if self.hasFocus and not self.disabled then
- gc:setColorRGB(40, 148, 184)
- gc:drawRect(self.x-2, self.y-2, self.w+3, self.h+3)
- gc:drawRect(self.x-3, self.y-3, self.w+5, self.h+5)
- end
- end
- function sButton:mouseMove(x,y)
- local isIn = (x>self.x and x<(self.x+self.w) and y>self.y and y<(self.y+self.h))
- self.pushed = self.forcePushed and isIn
- platform.window:invalidate()
- end
- function sButton:enterKey()
- if self.action then self.action() end
- end
- function sButton:mouseDown(x,y)
- if (x>self.x and x<(self.x+self.w) and y>self.y and y<(self.y+self.h)) then
- self.pushed = true
- self.forcePushed = true
- end
- platform.window:invalidate()
- end
- function sButton:mouseUp(x,y)
- self.pushed = false
- self.forcePushed = false
- if (x>self.x and x<(self.x+self.w) and y>self.y and y<(self.y+self.h)) then
- self:enterKey()
- end
- platform.window:invalidate()
- end
- ------------------------------------------------------------------
- -- Screen Widget --
- ------------------------------------------------------------------
- sScreen = class(WWidget)
- function sScreen:init(w, h)
- Widget.init(self)
- self.ww = w
- self.hh = h
- self.oy = 0
- self.ox = 0
- self.noloop = true
- end
- function sScreen:appended()
- self.oy = 0
- self.ox = 0
- end
- function sScreen:paint(gc)
- gc_clipRect(gc, "set", self.x, self.y, self.w, self.h)
- self.x = self.x + self.ox
- self.y = self.y + self.oy
- end
- function sScreen:postPaint(gc)
- gc_clipRect(gc, "reset")
- end
- function sScreen:setY(y)
- self.oy = y or self.oy
- end
- function sScreen:setX(x)
- self.ox = x or self.ox
- end
- function sScreen:showWidget()
- local w = self:getWidget()
- if not w then print("bye") return end
- local y = self.y - self.oy
- local wy = w.y - self.oy
- if w.y-2 < y then
- print("Moving up")
- self:setY(-(wy-y)+4)
- elseif w.y+w.h > y+self.h then
- print("moving down")
- self:setY(-(wy-(y+self.h)+w.h+2))
- end
- if self.focus == 1 then
- self:setY(0)
- end
- end
- function sScreen:getFocus(n)
- if n==-1 or n==1 then
- self:stealFocus()
- self:switchFocus(n, true)
- end
- end
- function sScreen:loop(n)
- self.parent:switchFocus(n)
- self:showWidget()
- end
- function sScreen:focusChange()
- self:showWidget()
- end
- function sScreen:loseFocus(n)
- if n and ((n >= 1 and self.focus+n<=#self.widgets) or (n <= -1 and self.focus+n>=1)) then
- self:switchFocus(n)
- return -1
- else
- self:stealFocus()
- end
- end
- ----------
- ------------------------------------------------------------------
- -- DivInput Widget --
- ------------------------------------------------------------------
- DivInput = class(WWidget)
- function DivInput:init(data)
- Widget.init(self)
- self.ww = 90
- self.hh = 40
- self.data = data
- self.label = data.label
- self.topText = data.topText
- self.ansTop = data.ansTop
- self.topInput = sInput()
- self.topInput.ww = 25
- self.topInput.hh = 15
- self.topInput.placeholder = data.topPlaceholder or " ?"
- self.topInput.border = false
- self.topInput.value = self.topText or ""
- self.topInput.disabled = data.disabled
- self.bottomText = data.bottomText
- self.ansBottom = data.ansBottom
- self.bottomInput = sInput()
- self.bottomInput.ww = 25
- self.bottomInput.hh = 15
- self.bottomInput.placeholder = data.bottomPlaceholder or " ?"
- self.bottomInput.border = false
- self.bottomInput.value = self.bottomText or ""
- self.bottomInput.disabled = data.disabled
- self.bottomInput.enterKey = function() self.parent:tabKey() end -- ahem
- end
- function DivInput:appended()
- local captionLabel = sLabel(self.label)
- self:appendWidget(captionLabel, "1", "25")
- self:appendWidget(sLabel("_____"), captionLabel.w+23, "10")
- self:appendWidget(self.topInput, captionLabel.w+28, "6")
- self:appendWidget(self.bottomInput, captionLabel.w+28, "58")
- end
- function DivInput:loseFocus()
- self.bottomInput.hasFocus = false
- self.topInput.hasFocus = false
- if #self.topInput.value > 0 and #self.bottomInput.value > 0 then
- self:checkValues()
- end
- end
- function DivInput:checkValues()
- if self.topInput.value ~= self.ansTop and self.topInput.value ~= self.ansTop:reverse() then
- self.topInput.textcolor = {255,0,0} else self.topInput.textcolor = {0,0,0}
- end
- if self.bottomInput.value ~= self.ansBottom and self.bottomInput.value ~= self.ansBottom:reverse() then
- self.bottomInput.textcolor = {255,0,0} else self.bottomInput.textcolor = {0,0,0}
- end
- if (self.topInput.value == self.ansTop or self.topInput.value == self.ansTop:reverse())
- and (self.bottomInput.value == self.ansBottom or self.bottomInput.value == self.ansBottom:reverse()) then
- self:disable()
- end
- end
- function DivInput:disable()
- self.topInput.disabled = true
- self.bottomInput.disabled = true
- end
- function DivInput:enterKey()
- if not self.topInput.hasFocus and not self.bottomInput.hasFocus then
- self.topInput:enterKey()
- return 0
- end
- if self.topInput.hasFocus then
- self.topInput:enterKey()
- else
- self.bottomInput:enterKey()
- end
- end
- function DivInput:postPaint(gc)
- if self.hasFocus then
- gc:setColorRGB(0,0,255)
- gc:drawRect(self.x, self.y, self.w, self.h)
- end
- end
- ------------------------------------------------------------------
- -- clickableText Widget --
- ------------------------------------------------------------------
- clickableText = class(Widget)
- function clickableText:init(width, height, text, action)
- --self.widget = widget
- self.text = text
- self.ww = width
- self.action = action
- self.hh = height
- self.lim = false
- self.color = {255,255,255}
- self.shadowColor = {0,0,0}
- self.font = {"serif", "b", 10}
- self.p = "top"
- end
- function clickableText:paint(gc)
- gc:setFont(uCol(self.font))
- --gc:drawRect(self.x, self.y, self.w, self.h)
- --[[local text = ""
- local ttext
- if self.lim then
- text, self.dw = textLim(gc, self.text, self.w)
- else
- text = self.text
- end]]
- gc:setColorRGB(uCol(self.shadowColor))
- gc:drawString(self.text, self.x-1, self.y+10-1, self.p)
- gc:setColorRGB(uCol(self.color))
- gc:drawString(self.text, self.x, self.y+10, self.p)
- end
- function clickableText:getFocus(n)
- if n then
- n = n < 0 and -1 or (n > 0 and 1 or 0)
- end
- if self.widget and not n then
- self.widget:giveFocus()
- elseif n then
- self.parent:switchFocus(n)
- end
- end
- function clickableText:mouseUp()
- if self.action then self.action() end
- end
- ------------------------------------------------------------------
- -- Pie Chart Widget --
- ------------------------------------------------------------------
- sPieChart = class(WWidget)
- function sPieChart:init(width, height, data, options)
- Widget.init(self)
- self.options = options
- self.ww = width
- self.hh = height
- self.data = data
- self.caption = data.caption
- self.borderColor = options.borderColor or {0,0,0}
- self.bgColor = options.bgColor or {255, 255, 255}
- self.show3d = self.options.show3d
- self.showNames = self.options.showNames
- self.sumOfValues = self:getSumOfValues()
- self:calculatePercentages()
- self:calculateAngles()
- end
- function sPieChart:appended()
- --override--
- self.ww = self.h
- self.w = self.h
- self.radius = math.floor(self.w/2)
- angleSumSoFar = 0
- for i,v in ipairs(self.data) do
- if self.showNames then
- sCaption = clickableText("30", "35", " ", function() self:selectNumber(i) end)
- -- to redo :( (or see with lua script at 1.2)
- self:appendWidget(sCaption, self.x+self.w/4.7+.6*(self.w/2*math.cos(3.14/180*(90-angleSumSoFar-(v.angle/2)))), self.y+self.h/3+.65*(self.h/2*math.sin(3.14/180*(90-angleSumSoFar-(v.angle/2)-180))))
- end
- angleSumSoFar = angleSumSoFar + v.angle
- end
- end
- function sPieChart:selectNumber(nbr)
- -- do whatever you want
- end
- function sPieChart:loseFocus()
- self:selectNumber(-1)
- end
- function sPieChart:getSumOfValues()
- local sum = 0
- for _,v in ipairs(self.data) do
- sum = sum + v.value
- end
- return sum
- end
- function sPieChart:calculatePercentages()
- for _,v in ipairs(self.data) do
- v.percentage = math.round(v.value*100/self.sumOfValues,2)
- end
- end
- function sPieChart:calculateAngles()
- for _,v in ipairs(self.data) do
- v.angle = math.round(v.percentage*90/25,2) -- 25% is 90 deg
- end
- end
- function sPieChart:paint(gc)
- if self.hasFocus then
- gc:setColorRGB(150, 150, 255)
- gc:drawArc(self.x-2, self.y-2, self.w+3, self.h+3, 0, 360)
- if self.show3d then gc:drawArc(self.x-2, self.y+7, self.w+4, self.h+2, 0, 360) end
- end
- if self.show3d then
- local angleSumSoFar = 0
- for i,v in ipairs(self.data) do
- gc:setColorRGB(.8*v.color[1], .8*v.color[2], .8*v.color[3])
- gc:fillArc(self.x-1, self.y+8, self.w+2, self.h, 90-angleSumSoFar-(v.angle)-.3, (v.angle))
- gc:fillArc(self.x, self.y+8, self.w+2, self.h, 90-angleSumSoFar-(v.angle)-.3, (v.angle))
- gc:fillArc(self.x, self.y+5, self.w+2, self.h, 90-angleSumSoFar-(v.angle)-.3, (v.angle))
- angleSumSoFar = angleSumSoFar + v.angle
- end
- gc:setColorRGB(unpack(self.borderColor))
- gc:drawArc(self.x, self.y+8, self.w, self.h, 0, 360)
- end
- gc:drawArc(self.x-1, self.y-1, self.w+2, self.h+2, 0, 360)
- gc:drawArc(self.x, self.y, self.w, self.h, 0, 360)
- local angleSumSoFar = 0
- for i,v in ipairs(self.data) do
- gc:setColorRGB(unpack(v.color))
- gc:fillArc(self.x, self.y, self.w, self.h, 90-angleSumSoFar-(v.angle)-.3, (v.angle))
- v.startAngle = 90-angleSumSoFar-(v.angle)-.3
- v.endAngle = v.angle
- gc:fillArc(self.x, self.y, self.w, self.h, 90-angleSumSoFar-(v.angle+1), (v.angle))
- angleSumSoFar = angleSumSoFar + v.angle
- end
- angleSumSoFar = 0
- for i,v in ipairs(self.data) do
- gc:setColorRGB(75,75,75)
- gc:drawLine(self.x+self.w/2, self.y+self.h/2, self.x+self.w/2+self.w/2*math.cos(3.14/180*(90-angleSumSoFar-(v.angle))), self.y+self.h/2+self.h/2*math.sin(3.14/180*(90-angleSumSoFar-(v.angle)-180)))
- if v.highlight then
- gc:setPen("medium", "smooth")
- gc:setColorRGB(0,0,0)
- gc:drawArc(self.x, self.y, self.w, self.h, 90-angleSumSoFar-(v.angle)+1, v.angle-2)
- gc:setPen("thin", "smooth")
- end
- if self.showNames then -- meh, to redo ?
- gc:setFont("serif", "b", 12)
- gc:setColorRGB(0,0,0)
- gc:drawString(v.name, self.x-1+self.w/3+.6*(self.w/2*math.cos(3.14/180*(90-angleSumSoFar-(v.angle/2)))), self.y-1+self.h/1.8+.65*(self.h/2*math.sin(3.14/180*(90-angleSumSoFar-(v.angle/2)-180))))
- gc:setColorRGB(255,255,255)
- gc:drawString(v.name, self.x+self.w/3+.6*(self.w/2*math.cos(3.14/180*(90-angleSumSoFar-(v.angle/2)))), self.y+self.h/1.8+.65*(self.h/2*math.sin(3.14/180*(90-angleSumSoFar-(v.angle/2)-180))))
- end
- angleSumSoFar = angleSumSoFar + v.angle
- end
- end
- --[[
- function CrossProduct(vect1, vect2)
- return { x= vect1.y*vect2.z-vect1.z*vect2.y, y = vect1.z*vect2.x-vect1.x*vect2.z, z = vect1.x*vect2.y-vect1.y*vect2.x }
- end
- function DotProduct(vect1, vect2)
- return vect1.x*vect2.x+vect1.y*vect2.y+vect1.z*vect2.z
- end
- function sPieChart:SameSide(p1,p2, a,b)
- cp1 = CrossProduct({x = b.x-a.x, y = b.y-a.y, z = 0}, {x = p1.x-a.x, y = p1.y-a.y, z = 0})
- cp2 = CrossProduct({x = b.x-a.x, y = b.y-a.y, z = 0}, {x = p2.x-a.x, y = p2.y-a.y, z = 0})
- return DotProduct( {x = cp1.x, y = cp1.y, z = cp1.z}, {x = cp2.x, y = cp2.y, z = cp2.z} ) >= 0
- end
- function sPieChart:isPointInTriangle(p, a,b,c)
- return self:SameSide(p,a, b,c) and self:SameSide(p,b, a,c) and self:SameSide(p,c, a,b)
- end
- print( sPieChart:isPointInTriangle( {x=1, y=1, z=0}, {x=0, y=0, z=0},{x=1, y=3, z=0},{x=3, y=1, z=0} ) )
- ]]-- not needed anyway
- function sPieChart:distanceBetween(p1,p2)
- return math.sqrt((p2.x-p1.x)^2+(p2.y-p1.y)^2)
- end
- function sPieChart:mouseUpDISABLED(xx,yy) -- p is {x,y}
- local p = {x=xx, y=yy, angle=math.abs(180/3.142*math.atan((yy-self.y)/(xx-self.x)))}
- local center = {x=self.x+self.radius, y=self.y+self.radius}
- local angleSumSoFar = 0
- local tmp = 0
- for i,v in ipairs(self.data) do
- -- check for each v : ((distance from p to center) <= radius) AND (startAngle < arctan(y/x) < endAngle)
- --print("part "..i, self:distanceBetween(p,center)<=self.radius , math.abs(90-angleSumSoFar-(v.angle+1))> p.angle , p.angle < math.abs((v.angle)) )
- --print("------")
- if self:distanceBetween(p,center)<=self.radius and math.abs(v.startAngle) < p.angle and p.angle < math.abs(v.angle) then
- --print(i)
- tmp = i
- --break
- else
- v.highlight = false
- end
- angleSumSoFar = angleSumSoFar + v.angle
- end
- --if tmp > 0 then self.data[tmp].highlight = true end
- end
- ------------------------------------------------------------------
- -- Slider Widget --
- ------------------------------------------------------------------
- sSlider = class(Widget)
- function sSlider:init(width, height, options)
- self.options = options
- self.ww = width
- self.hh = height
- self.min = options.min or 0
- self.max = options.max or 100
- self.step = options.step or ((self.max-self.min)/10)
- --if self.min > self.max then self.min, self.max = self.max, self.min end
- self.reverse = self.min<self.max
- self.showGraduations = options.showGraduations or true
- self.showBounds = options.showBounds or false
- self.defaultValue = options.defaultValue or math.ceil((self.max-self.min)/2)
- self.internalValue = self.defaultValue
- self.borderColor = options.borderColor or {40, 148, 184}
- self.bgColor = options.bgColor or {255, 255, 255}
- if not options.line then options.line = {} end
- self.line = { thickness = options.line.thickness or 5,
- bgColor = options.line.bgColor or {200,200,200},
- borderColor = options.line.borderColor or {0,0,0} }
- self.cursor = {}
- self.value = self.max-self.internalValue
- self.pValue = math.ceil(self.value*100/self.max)
- -- ....
- end
- function sSlider:value2px(value)
- return self.orientation == "vertical" and math.floor((self.y+0.94*value/(self.max-self.min)*(self.h))-3) or math.floor((self.x+(0.94*value)/(self.max-self.min)*(self.w))-3)
- end
- function sSlider:px2value(px)
- return self.orientation == "vertical" and math.floor(((px-self.y)*(self.max-self.min))/(self.h)) or math.floor(((px-self.x)*(self.max-self.min))/(self.w))
- end
- function sSlider:appended()
- self.orientation = (tonumber(self.hh) >= tonumber(self.ww)) and "vertical" or "horizontal"
- self.graduations = self.options.graduations or (self.orientation == "vertical" and math.ceil(self.h/30) or math.ceil(self.w/20) )
- self.graduationsStep = self.options.graduationsStep or (self.max-self.min)/(self.graduations+2)
- self:updateCursor()
- end
- function sSlider:updateCursor()
- self.cursor = { x = (self.orientation == "vertical") and self.x+(self.w-self.line.thickness)/2-2 or self:value2px(self.internalValue),
- y = (self.orientation == "vertical") and self:value2px(self.internalValue) or self.y+(self.h-self.line.thickness)/2-2,
- radius=8 }
- self.value = self.orientation == "vertical" and self.max-self.internalValue or self.internalValue
- self.pValue = math.ceil(self.value*100/self.max)
- self.parent:update()
- end
- function sSlider:updateValue()
- self.internalValue = (self.orientation == "vertical") and self:px2value(self.cursor.y) or self:px2value(self.cursor.x)
- if self.internalValue < self.min then self.internalValue = self.min end
- if self.internalValue > self.max then self.internalValue = self.max end
- end
- function sSlider:paint(gc)
- gc:setColorRGB(unpack(self.bgColor))
- --gc:fillRect(self.x, self.y, self.w, self.h)
- gc:setColorRGB(unpack(self.line.bgColor))
- if self.orientation == "vertical" then
- gc:fillRect(self.x+(self.w-self.line.thickness)/2, self.y, self.line.thickness, self.h)
- else
- gc:fillRect(self.x, self.y+(self.h-self.line.thickness)/2, self.w, self.line.thickness)
- end
- gc:setColorRGB(0,0,0)
- if self.orientation == "vertical" then
- gc:fillRect(self.x+self.w/3, self.y-1, self.w/3.2, 2)
- gc:fillRect(self.x+self.w/3, self.y+self.h-1, self.w/3.2, 2)
- if self.showBounds then
- gc:drawString(self.max,self.x+(self.w+self.line.thickness+8)/2, self.y, "middle")
- gc:drawString(self.min,self.x+(self.w+self.line.thickness+8)/2, self.y+self.h-5, "middle")
- end
- else
- gc:fillRect(self.x-1, self.y+self.h/4-1, 2, self.h/2)
- gc:fillRect(self.x+self.w-1, self.y+self.h/4, 2, self.h/2)
- if self.showBounds then
- gc:drawString(self.min, self.x, self.y, "middle")
- gc:drawString(self.max, self.x+self.w-10, self.y, "middle")
- end
- end
- fillCircle(gc,self.cursor.x,self.cursor.y, 8)
- gc:setColorRGB(unpack(self.borderColor))
- drawCircle(gc,self.cursor.x,self.cursor.y, 8)
- if self.hasFocus then
- gc:setColorRGB(unpack(self.borderColor))
- fillCircle(gc,self.cursor.x+3,self.cursor.y+3, 2.5)
- end
- end
- function sSlider:grabDown(x,y)
- print("grabDown")
- self.isGrabbing = not self.isGrabbing
- end
- function sSlider:mouseUp(x,y)
- cursor.set("default")
- self.isGrabbing = false
- end
- function sSlider:mouseDown(x,y)
- if math.abs(self.cursor.x+self.cursor.radius/2-x) <= self.cursor.radius and math.abs(self.cursor.y+self.cursor.radius/2-y) <= self.cursor.radius then
- self.isGrabbing = true
- end
- end
- function sSlider:mouseMove(x,y)
- if self.isGrabbing then
- cursor.set("drag grab")
- if self.orientation == "vertical" then
- self.cursor.y = y+2
- self:updateValue()
- else
- self.cursor.x = x+2
- self:updateValue()
- end
- self:updateCursor()
- else
- if math.abs(self.cursor.x+self.cursor.radius/2-x) <= 1.6*self.cursor.radius/2 and math.abs(self.cursor.y+self.cursor.radius/2-y) <= 1.6*self.cursor.radius/2 then
- cursor.set("hand pointer")
- else
- cursor.set("default")
- end
- end
- end
- ------------------------------------------------------
- -- s2DArray Widget --
- ------------------------------------------------------
- s2DArray = class(WWidget)
- function s2DArray:init(width, height, data)
- Widget.init(self)
- self.width = width
- self.ww = width
- self.height = height
- self.hh = height
- self.data = data or {}
- self.columns = (#self.data > 0) and #(self.data[1]) or 0
- self.rows = #self.data or 0
- --setmetatable(self.data, { __index = function() return "" end })
- self.content = {}
- self.totalAttempts = 0
- self.hasFinished = false
- self.centeredText = true
- self.totalAnswers = self.data.totalAnswers or 0
- self.correctAnswers = 0
- self.maxAttempts = 5
- end
- function s2DArray:appended()
- for j=1, self.rows do
- self.content[j] = {}
- for i=1, self.columns do
- local theInput = sInput()
- theInput.showBorder = true
- theInput.ww = self.w/self.columns
- theInput.hh = self.h/self.rows
- theInput.id = {i,j}
- theInput.centeredText = self.centeredText or false -- lulz bool logic
- theInput.value = self.data[j][i].text or ""
- theInput.placeholder = self.data[j][i].placeholder or ""
- theInput.font[2] = (self.data[j][i].isHeader or self.data[j][i].isEditable) and "b" or "r" -- bold or regular
- theInput.number = self.data[j][i].numbersOnly or false
- theInput.disabled = not self.data[j][i].isEditable
- function theInput:enterKey()
- self.parent:checkContent(self.id[2], self.id[1])
- self.parent:switchFocus(2)--self:getNextEditableCell(i,j))
- end
- function theInput:arrowKey(arrw)
- if not self.disabled then
- self.parent:checkContent(self.id[2], self.id[1])
- if arrw == "up" then
- if self.parent.content[self.id[2]-1] and not self.parent.content[self.id[2]-1][self.id[1]].disabled then
- self.parent:switchFocus(-2)
- end
- elseif arrw == "down" then
- if self.parent.content[self.id[2]+1] and not self.parent.content[self.id[2]+1][self.id[1]].disabled then
- self.parent:switchFocus(2)
- end
- elseif arrw == "left" then
- if self.parent.content[self.id[2]][self.id[1]-1] and not self.parent.content[self.id[2]][self.id[1]-1].disabled then
- self.parent:switchFocus(-1)
- end
- elseif arrw == "right" then
- if self.parent.content[self.id[2]][self.id[1]+1] and not self.parent.content[self.id[2]][self.id[1]+1].disabled then
- self.parent:switchFocus(1)
- end
- end
- end
- end
- self.content[j][i] = theInput
- self:appendWidget(self.content[j][i], (self.w/self.columns)*(i-1), (self.h/self.rows)*(j-1))
- end
- end
- end
- function s2DArray:getNextEditableCell(col, row)
- return 0
- end
- function s2DArray:displayExpected()
- for j=1, self.rows do
- for i=1, self.columns do
- self.content[j][i].disabled = true
- self.content[j][i].value = self.data[j][i].answer or self.content[j][i].value
- end
- end
- print("Disabled inputs + showing answers")
- end
- function s2DArray:paint(gc)
- if self.hasFocus then
- gc:setColorRGB(40, 148, 184)
- gc:drawRect(self.x-1, self.y-1, self.w+3, self.h+2)
- end
- end
- function s2DArray:loseFocus()
- self.hasFocus = false -- useless (works without)
- for j=1, self.rows do
- for i=1, self.columns do
- self.content[j][i].hasFocus = false
- end
- end
- end
- function s2DArray:checkContent(row, col)
- local expectedValue = self.data[row][col].answer or ""
- local otherExpectedValue = self.data[row][col].optAnswer or ""
- local theInput = self.content[row][col]
- --print("checking content at R".. row.."C"..col.." : is ", theInput.value or "", " == ", expectedValue, " ? ", ((self.content[row][col].value or "") == expectedValue))
- local isGood = (theInput.value == expectedValue) or (theInput.value == otherExpectedValue)
- if not theInput.disabled and not self.hasFinished and not (self.totalAttempts > self.maxAttempts) and #theInput.value>0 then
- if not isGood then
- print("Wrong !!")
- self.content[row][col].bgcolor = {255,0,0}
- self.totalAttempts = self.totalAttempts + 1
- else
- print("Correct !!")
- self.content[row][col].bgcolor = {0,255,0}
- self.content[row][col].disabled = true
- self.content[row][col].value = self.data[row][col].answer or self.content[row][col].value
- self.correctAnswers = self.correctAnswers + 1
- end
- if self.totalAttempts == self.maxAttempts or self.correctAnswers == self.totalAnswers then
- self.hasFinished = true
- self:displayExpected()
- end
- end
- end
- ----------
- function on.timer() current_screen():timer() screenRefresh() end
- function on.arrowKey(arrw) current_screen():arrowKey(arrw) screenRefresh() end
- function on.enterKey() current_screen():enterKey() screenRefresh() end
- function on.escapeKey() current_screen():escapeKey() screenRefresh() end
- function on.tabKey() current_screen():tabKey() screenRefresh() end
- function on.backtabKey() current_screen():backtabKey() screenRefresh() end
- function on.clearKey() current_screen():clearKey() screenRefresh() end
- function on.charIn(ch) current_screen():charIn(ch) screenRefresh() end
- function on.backspaceKey() current_screen():backspaceKey() screenRefresh() end
- function on.mouseDown(x, y) current_screen():mouseDown(x, y) screenRefresh() end
- function on.mouseUp(x, y) current_screen():mouseUp(x, y) screenRefresh() end
- function on.mouseMove(x, y) current_screen():mouseMove(x, y) screenRefresh() end
- function on.grabDown(x, y) current_screen():grabDown(x, y) screenRefresh() end
- ------------------------------
- --- ETK Library finished ---
- ------------------------------
- function showPopup()
- StatsWindow = Dialog("Popup window", 150, 20, 268, 164)
- local StatsStr = [[Hello world
- Put any text here...
- any text here...
- any text here...
- ]]
- local StatsOkButton = sButton("OK")
- for i, line in ipairs(StatsStr:split("\n")) do
- local StatsText = sLabel(line)
- StatsWindow:appendWidget(StatsText, 10, 27 + i*14-12)
- end
- StatsWindow:appendWidget(StatsOkButton,-10,-5)
- function StatsWindow:postPaint(gc)
- nativeBar(gc, self, self.h-40)
- on.help = function() return 0 end
- end
- StatsOkButton:giveFocus()
- function StatsWindow:escapeKey()
- StatsOkButton:action()
- end
- function StatsWindow:arrowKey(arrw)
- if arrw == "up" then
- self:backtabKey()
- elseif arrw == "down" then
- self:tabKey()
- end
- end
- function StatsOkButton:action()
- remove_screen(StatsWindow)
- end
- push_screen(StatsWindow)
- end
- -----------------
- ------Main:------
- -----------------
- Main = WScreen()
- Main.initTimer = true
- Main.divInputs = {
- {label = "sin(A) =", ansTop = "BC", ansBottom="AC", topText = "BC", bottomText="AC", disabled=true},
- {label = "cos(A) =", ansTop = "AB", ansBottom="AC"}
- }
- Main.pieChartData = {
- { name="Cycle", value=12, color={0,0,230} },
- { name="Bus", value=16, color={250,0,0} },
- { name="Taxi", value=8, color={0,200,0} },
- { name="Walk", value=8, color={200,0,180} },
- { name=" Car", value=4, color={115,115,250} },
- caption="students",
- showNames = true
- }
- Main.arrayData =
- {
- { { text="Wages", isHeader=true }, { text="50-100" }, { text="100-150" }},
- { { text="Freq", isHeader=true }, { placeholder=" ? ", isEditable=true, answer="5", numbersOnly=true }, { placeholder=" ? ", isEditable=true, answer="4", numbersOnly=true }},
- totalAnswers = 3
- }
- function Main:checkValue(obj, ans)
- if #obj.value > 0 and not obj.disabled then
- obj.tries = obj.tries and (obj.tries + 1) or 1
- if obj.value == ans then
- obj.disabled = true
- else
- if obj.tries > 1 then
- obj.value = ans
- obj.disabled = true
- end
- end
- end
- end
- function Main:setup()
- self.lbl1 = sLabel(" + 5 = 5")
- self.inp1 = sInput(function() Main:checkValue(self.inp1, "0") end)
- self.inp1.value = "" self.inp1.number = true
- self.sliderLabel = sLabel("Slider :", {style="b", decoration="underline"} )
- self:appendWidget(self.sliderLabel, 5, 0)
- self:appendWidget(sLabel("Italic Underline", {style="i", decoration="underline"}), "33", 0)
- self:appendWidget(sLabel("A Bold Text", {style="b"}), -70, 0)
- self:appendWidget(sLabel("Standard Input :", {style="b", decoration="underline"} ), 5, "22")
- self:appendWidget(self.lbl1, "2", "34")
- self:appendWidget(self.inp1, "2", "34")
- local popupButton = sButton("Button")
- function popupButton:action() showPopup() end
- self:appendWidget(popupButton, "45", "83")
- local disabledButton = sButton("Disabled Button")
- disabledButton.disabled = true
- self:appendWidget(disabledButton, "65", "83")
- self:appendWidget(sLabel("Pie Chart :", {style="b", decoration="underline"} ), "42", "18")
- self.thePieChart1 = sPieChart( "38", "38", self.pieChartData, {show3d = false, showNames = true} )
- self:appendWidget(self.thePieChart1, "68", "12")
- self:appendWidget(sLabel("Fraction Inputs :", {style="b", decoration="underline"} ), 5, "48")
- self:appendWidget(DivInput(Main.divInputs[1]), "2", "58")
- self:appendWidget(DivInput(Main.divInputs[2]), "2", "78")
- self:appendWidget(sLabel("Array Inputs :", {style="b", decoration="underline"} ), "42", "48")
- local arrayInfo = s2DArray("59", "16", self.arrayData)
- self:appendWidget(arrayInfo, "40", "60")
- self.theSlider = sSlider(80, 20, {min = 0, max = 255, showBounds=false} )
- self:appendWidget(self.theSlider, 5, "10")
- end
- function Main:paint(gc)
- -- extra things you want to draw, before the widgets.
- end
- function Main:postPaint(gc)
- -- extra things you want to draw, after the widgets.
- end
- function Main:resize(x,y)
- Main.initTimer = true
- timer.start(0.1)
- end
- function Main:timer(ch)
- if self.initTimer then
- timer.stop()
- self.initTimer = false
- self:cleanWidgets()
- self:setup()
- end
- end
- function Main:update()
- self.sliderLabel.xx = self.theSlider.pValue
- self:invalidate()
- end
- Main:setup()
- ----------------------
- --- Other events ---
- ----------------------
- function on.construction()
- end
- function on.paint(gc)
- for _, screen in pairs(Screens) do
- screen:draw(gc)
- end
- end
- function on.deactivate()
- activated = false
- end
- function on.activate()
- activated = true
- end
- function on.resize(x, y)
- -- Global Ratio Constants for On-Calc (shouldn't be used often though...)
- kXRatio = x / 318
- kYRatio = y / 212
- kXSize = x
- kYSize = y
- for _,screen in pairs(Screens) do
- screen:resize(x, y)
- end
- platform.window:invalidate() -- redraw everything
- end
- -----------------
- -----Start !-----
- -----------------
- push_screen(Main)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement