-------------------------------------------------------------------------------- -- Drawables class -------------------- -- Keeps all the graphical elements composing the table with their position. -- Used to redraw the table without recalculating everything when only ratio -- or offset are changed -------------------------------------------------------------------------------- Drawables = class() function Drawables:init() self:reset() end function Drawables:add_line(x1, y1, x2, y2) self.numlines = self.numlines + 1 self.lines[self.numlines] = {x1, y1, x2, y2} end function Drawables:add_text(text, x, y, pos, size) self.numtexts = self.numtexts + 1 self.texts[self.numtexts] = {text, x, y, pos, size} end function Drawables:add_arrow(x1, y1, x2, y2, ratio, openness) ratio = ratio or 0.08 openness = openness or 0.8 local vec = {x2 - x1, y2 - y1} local perp = {vec[2], -vec[1]} local b1 = {ratio * (-vec[1] + openness * perp[1]), ratio * (-vec[2] + openness * perp[2])} -- ((-vec) + openness * perp) * ratio local b2 = {ratio * (-vec[1] - openness * perp[1]), ratio * (-vec[2] - openness * perp[2])} -- ((-vec) - openness * perp) * ratio self:add_line(x1, y1, x2, y2) self:add_line(x2, y2, x2 + b1[1], y2 + b1[2]) self:add_line(x2, y2, x2 + b2[1], y2 + b2[2]) end function Drawables:reset() self.numtexts = 0 self.texts = {} self.numlines = 0 self.lines = {} end -------------------------------------------------------------------------------- -- PrettyPrint -------------------------------------------------------------------------------- -- Handles the display of mathematical expressions -------------------------------------------------------------------------------- PrettyPrint = {} PrettyPrint.first_column_width = 50 PrettyPrint.column_width = 35 -- in fact, it is the half of the width of a column PrettyPrint.first_line_height = 60 PrettyPrint.second_line_height = 95 PrettyPrint.third_line_height = 120 PrettyPrint.fourth_line_height = 200 PrettyPrint.limit_margin = 8 PrettyPrint.max_size = 12 PrettyPrint.arrow_h_margin = 8 PrettyPrint.arrow_v_margin = 8 PrettyPrint.box_margin = 2 function PrettyPrint.string_matrix(s) -- Returns the matrix corresponding to a string in the correct format return {{s}, {0}, {0}} end function PrettyPrint.get_limit_matrix(i) return var.recall("luarep.limit"..i) end function PrettyPrint.get_fct_matrix() return var.recall("luarep.fctmatrix") end function PrettyPrint.get_value_matrix(i) return var.recall("luarep.value"..i) end function PrettyPrint.exponent_size(base_size) return (base_size+12)/3 --min size is 6 end function PrettyPrint.quotient_h_margin(base_size) --horizontal margin for the quotient line return base_size / 3 end function PrettyPrint.quotient_v_margin(base_size) --vertical return base_size / 4 end function PrettyPrint.sqrt_left_margin(base_size) return base_size / 1.5 end function PrettyPrint.sqrt_right_margin(base_size) return base_size / 4 end function PrettyPrint.sqrt_top_margin(base_size) return base_size / 3 end function PrettyPrint.sqrt_bottom_margin(base_size) return base_size / 8 end function PrettyPrint.abs_h_margin(base_size) return base_size / 3 end function PrettyPrint.get_height(matrix, offset, base_size) --offset is the current offset in the matrix, we compute only the part depending on this offset (recursive func) --set computed values in row 4 to avoid future recomputations --row 6 is used for vertical adjustments (currently not implemented, will be used for things like a + (b/c)/d) matrix[4] = matrix[4] or {} --matrix[6] = matrix[6] or {} if matrix[2][offset] == 0 then --immediate value matrix[4][offset] = base_size --matrix[6][offset] = 0 elseif matrix[3][offset] == 0 then --function call if matrix[1][offset] == string.uchar(8730) then matrix[4][offset] = PrettyPrint.sqrt_top_margin(base_size) + PrettyPrint.sqrt_bottom_margin(base_size) + PrettyPrint.get_height(matrix, matrix[2][offset], base_size) else matrix[4][offset] = PrettyPrint.get_height(matrix, matrix[2][offset], base_size) end --matrix[6][offset] = matrix[6][matrix[2][offset]] elseif matrix[1][offset] == "/" then matrix[4][offset] = 2 * PrettyPrint.quotient_v_margin(base_size) + PrettyPrint.get_height(matrix, matrix[2][offset], base_size) + PrettyPrint.get_height(matrix, matrix[3][offset], base_size) --matrix[6][offset] = matrix[4][matrix[2][offset]] - matrix[4][matrix[3][offset]] elseif matrix[1][offset] == "+" or matrix[1][offset] == "-" or matrix[1][offset] == string.uchar(0x2219) then matrix[4][offset] = math.max(PrettyPrint.get_height(matrix, matrix[2][offset], base_size), PrettyPrint.get_height(matrix, matrix[3][offset], base_size)) --[[ local hl = PrettyPrint.get_height(matrix, matrix[2][offset], base_size) local dl = matrix[6][matrix[2][offset]] --[[ local hr = PrettyPrint.get_height(matrix, matrix[3][offset], base_size) local dr = matrix[6][matrix[3][offset]] --[[ local up = math.max(hl / 2 + dl, hr / 2 + dl) local down = matrix[6][offset] = ]]-- elseif matrix[1][offset] == "^" then matrix[4][offset] = PrettyPrint.get_height(matrix, matrix[2][offset], base_size) - base_size * 3 / 4 + PrettyPrint.get_height(matrix, matrix[3][offset], PrettyPrint.exponent_size(base_size)) end return matrix[4][offset] end function PrettyPrint.get_width(matrix, offset, previous_operator, base_size) --previous_operator is used to know whether or not we need parentheses (used for get_width only) --the rest is like get_height --set computed values in row 5 to avoid future recomputations local need_parentheses = false if matrix[2][offset] == 0 and type(matrix[1][offset]) == "string" then if matrix[1][offset]:len() > 2 then if matrix[1][offset]:sub(1, 1) == "\"" then matrix[1][offset] = matrix[1][offset]:sub(2, -2) --remove double quotes end end end local operator = matrix[1][offset] if operator == "*" then operator = string.uchar(0x2219) --middle dot, as used in the real nspire math print matrix[1][offset] = operator --done only here because get_width is always called first (!) end if (previous_operator == string.uchar(0x2219) or previous_operator == string.uchar(8722)) and (operator == "+" or operator == "-") then need_parentheses = true end local gc = platform.gc() gc:begin() local parwidth, opwidth = 0 if base_size > 6 then gc:setFont("sansserif", "r", base_size) parwidth = gc:getStringWidth("()") opwidth = gc:getStringWidth(matrix[1][offset]) else gc:setFont("sansserif", "r", 6) local ratio = base_size / 6 parwidth = ratio * gc:getStringWidth("()") opwidth = ratio * gc:getStringWidth(matrix[1][offset]) end gc:finish() matrix[5] = matrix[5] or {} if matrix[2][offset] == 0 then --immediate value matrix[5][offset] = opwidth elseif matrix[3][offset] == 0 then --function call if matrix[1][offset] == string.uchar(8722) then --"small" minus matrix[5][offset] = opwidth + PrettyPrint.get_width(matrix, matrix[2][offset], matrix[1][offset], base_size) elseif matrix[1][offset] == string.uchar(8730) then matrix[5][offset] = PrettyPrint.sqrt_left_margin(base_size) + PrettyPrint.sqrt_right_margin(base_size) + PrettyPrint.get_width(matrix, matrix[2][offset], matrix[1][offset], base_size) elseif matrix[1][offset] == "abs" then matrix[5][offset] = 2 * PrettyPrint.abs_h_margin(base_size) + PrettyPrint.get_width(matrix, matrix[2][offset], matrix[1][offset], base_size) else matrix[5][offset] = opwidth + parwidth + PrettyPrint.get_width(matrix, matrix[2][offset], matrix[1][offset], base_size) end elseif matrix[1][offset] == "/" then matrix[5][offset] = 2 * PrettyPrint.quotient_h_margin(base_size) + math.max(PrettyPrint.get_width(matrix, matrix[2][offset], matrix[1][offset], base_size), PrettyPrint.get_width(matrix, matrix[3][offset], matrix[1][offset], base_size)) elseif matrix[1][offset] == "+" or matrix[1][offset] == "-" or matrix[1][offset] == string.uchar(0x2219) then if need_parentheses then matrix[5][offset] = opwidth + parwidth + PrettyPrint.get_width(matrix, matrix[2][offset], matrix[1][offset], base_size) + PrettyPrint.get_width(matrix, matrix[3][offset], matrix[1][offset], base_size) else matrix[5][offset] = opwidth + PrettyPrint.get_width(matrix, matrix[2][offset], matrix[1][offset], base_size) + PrettyPrint.get_width(matrix, matrix[3][offset], matrix[1][offset], base_size) end elseif matrix[1][offset] == "^" then matrix[5][offset] = PrettyPrint.get_width(matrix, matrix[2][offset], matrix[1][offset], base_size) + PrettyPrint.get_width(matrix, matrix[3][offset], matrix[1][offset], PrettyPrint.exponent_size(base_size)) end return matrix[5][offset] end function PrettyPrint.PrettyPrint(drawables, matrix, up, down, left, right, offset, previous_operator, base_size) --adds elements needed to represent the given matrix in the drawables --when calling it use only the first 6 parameters local gc = platform.gc() gc:begin() offset = offset or 1 previous_operator = previous_operator or "" local available_width = right - left local available_height = down - up if not base_size then -- first call local width_12 = PrettyPrint.get_width(matrix, 1, "", 12) local height_12 = PrettyPrint.get_height(matrix, 1, 12) local ratio = math.min(available_width / width_12, available_height / height_12) base_size = ratio * 12 if base_size > PrettyPrint.max_size then base_size = PrettyPrint.max_size end width = PrettyPrint.get_width(matrix, 1, "", base_size) --actualise values contained in rows 4 and 5 of the matrix height = PrettyPrint.get_height(matrix, 1, base_size) end local parwidth = 0 if base_size > 6 then gc:setFont("sansserif", "r", base_size) parwidth = gc:getStringWidth("()") / 2 else local ratio = base_size / 6 gc:setFont("sansserif", "r", 6) parwidth = gc:getStringWidth("()") * ratio / 2 end gc:finish() h_correction = (available_width - matrix[5][offset]) / 2 --center the expression in the area v_correction = (available_height - matrix[4][offset]) / 2 up = up + v_correction down = down - v_correction left = left + h_correction right = right - h_correction if matrix[2][offset] == 0 then --immediate value drawables:add_text(matrix[1][offset], left, (down + up) / 2, "middle", base_size) elseif matrix[3][offset] == 0 then --function call if matrix[1][offset] == string.uchar(8722) then drawables:add_text(matrix[1][offset], left, (down + up) / 2, "middle", base_size) PrettyPrint.PrettyPrint(drawables, matrix, up, down, right - matrix[5][matrix[2][offset]], right, matrix[2][offset], matrix[1][offset], base_size) elseif matrix[1][offset] == string.uchar(8730) then --square root drawables:add_line(left + PrettyPrint.sqrt_left_margin(base_size), up + PrettyPrint.sqrt_top_margin(base_size) / 2, right - PrettyPrint.sqrt_right_margin(base_size) / 2, up + PrettyPrint.sqrt_top_margin(base_size) / 2) drawables:add_line(left + PrettyPrint.sqrt_left_margin(base_size) / 2, down, left + PrettyPrint.sqrt_left_margin(base_size) , up + PrettyPrint.sqrt_top_margin(base_size) / 2) drawables:add_line(left, (up + 2 * down) / 3, left + PrettyPrint.sqrt_left_margin(base_size) / 2, down) PrettyPrint.PrettyPrint(drawables, matrix, up + PrettyPrint.sqrt_top_margin(base_size), down - PrettyPrint.sqrt_bottom_margin(base_size), left + PrettyPrint.sqrt_left_margin(base_size), right - PrettyPrint.sqrt_right_margin(base_size), matrix[2][offset], matrix[1][offset], base_size) elseif matrix[1][offset] == "abs" then drawables:add_line(left + PrettyPrint.abs_h_margin(base_size) / 2, up, left + PrettyPrint.abs_h_margin(base_size) / 2, down) drawables:add_line(right - PrettyPrint.abs_h_margin(base_size) / 2, up, right - PrettyPrint.abs_h_margin(base_size) / 2, down) PrettyPrint.PrettyPrint(drawables, matrix, up, down, left + PrettyPrint.abs_h_margin(base_size), right - PrettyPrint.abs_h_margin(base_size), matrix[2][offset], matrix[1][offset], base_size) else drawables:add_text(matrix[1][offset].."(", left, (down + up) / 2, "middle", base_size) drawables:add_text(")", right - parwidth, (down + up) / 2, "middle", base_size) PrettyPrint.PrettyPrint(drawables, matrix, up, down, right - parwidth - matrix[5][matrix[2][offset]], right - parwidth, matrix[2][offset], matrix[1][offset], base_size) end elseif matrix[1][offset] == "/" then local height_up = matrix[4][matrix[2][offset]] local height_down = matrix[4][matrix[3][offset]] drawables:add_line(left, (up + height_up + down - height_down) / 2, right, (up + height_up + down - height_down) / 2) PrettyPrint.PrettyPrint(drawables, matrix, up, up + height_up, left, right, matrix[2][offset], matrix[1][offset], base_size) PrettyPrint.PrettyPrint(drawables, matrix, down - height_down, down, left, right, matrix[3][offset], matrix[1][offest], base_size) elseif matrix[1][offset] == "+" or matrix[1][offset] == "-" or matrix[1][offset] == string.uchar(0x2219) then local width_left = matrix[5][matrix[2][offset]] local width_right = matrix[5][matrix[3][offset]] local operator = matrix[1][offset] if (previous_operator == string.uchar(0x2219) or previous_operator == string.uchar(8722)) and (operator == "-" or operator == "+") then --need parentheses drawables:add_text(matrix[1][offset], left + width_left + parwidth, (up + down) / 2, "middle", base_size) drawables:add_text("(", left, (up + down) / 2, "middle", base_size) drawables:add_text(")", right - parwidth, (up + down) / 2, "middle", base_size) PrettyPrint.PrettyPrint(drawables, matrix, up, down, left + parwidth, left + parwidth + width_left, matrix[2][offset], matrix[1][offset], base_size) PrettyPrint.PrettyPrint(drawables, matrix, up, down, right - width_right - parwidth, right - parwidth, matrix[3][offset], matrix[1][offset], base_size) else drawables:add_text(matrix[1][offset], left + width_left, (up + down) / 2, "middle", base_size) PrettyPrint.PrettyPrint(drawables, matrix, up, down, left, left + width_left, matrix[2][offset], matrix[1][offset], base_size) PrettyPrint.PrettyPrint(drawables, matrix, up, down, right - width_right, right, matrix[3][offset], matrix[1][offset], base_size) end elseif matrix[1][offset] == "^" then local left_width = matrix[5][matrix[2][offset]] PrettyPrint.PrettyPrint(drawables, matrix, up, down, left, left+left_width, matrix[2][offset], matrix[1][offset], base_size) PrettyPrint.PrettyPrint(drawables, matrix, up, down - base_size * 3 / 4, left + left_width, right, matrix[3][offset], matrix[1][offset], PrettyPrint.exponent_size(base_size)) end end -------------------------------------------------------------------------------- -- Table class -------------------- -- Used to precalculate and draw the variation table -------------------------------------------------------------------------------- Table = class() function Table:init() self.xoffset = 0 self.yoffset = 0 self.width = 0 self.height = 0 self.scale = 1 self.fct = "luarep.fctmatrix" self.var = "" self.mat = {} self.valuesstrs = {} self.valuesmats = {} self.drawables = Drawables() self.lastMousePos = {0,0} end function Table:calculate() self.xoffset = 0 self.yoffset = 0 self.height = PrettyPrint.fourth_line_height self.drawables:reset() self.var = var.recallstr("luarep.var") self.mat = var.recall("luarep.tablematrix") --First column, vertical lines --Horizontal ones will be drawn at the end self.drawables:add_line(0, PrettyPrint.first_line_height, 0, PrettyPrint.fourth_line_height) self.drawables:add_line(PrettyPrint.first_column_width, PrettyPrint.first_line_height, PrettyPrint.first_column_width, PrettyPrint.fourth_line_height) PrettyPrint.PrettyPrint(self.drawables, PrettyPrint.string_matrix(self.var), PrettyPrint.first_line_height, PrettyPrint.second_line_height, 0, PrettyPrint.first_column_width) PrettyPrint.PrettyPrint(self.drawables, PrettyPrint.string_matrix("f'("..self.var..")"), PrettyPrint.second_line_height, PrettyPrint.third_line_height, 0, PrettyPrint.first_column_width) PrettyPrint.PrettyPrint(self.drawables, PrettyPrint.string_matrix("var f"), PrettyPrint.third_line_height, PrettyPrint.fourth_line_height, 0, PrettyPrint.first_column_width) local i = 2 while self.mat[1][i] do if (i % 2) == 0 then --draw a value, the corresponding limit and the 0 for the derivate PrettyPrint.PrettyPrint(self.drawables, PrettyPrint.get_value_matrix(i/2), PrettyPrint.first_line_height + PrettyPrint.box_margin, PrettyPrint.second_line_height - PrettyPrint.box_margin, PrettyPrint.first_column_width + (i-2) * PrettyPrint.column_width + PrettyPrint.box_margin, PrettyPrint.first_column_width + i * PrettyPrint.column_width - PrettyPrint.box_margin) PrettyPrint.PrettyPrint(self.drawables, PrettyPrint.get_limit_matrix(i/2), PrettyPrint.third_line_height + PrettyPrint.limit_margin, PrettyPrint.fourth_line_height - PrettyPrint.limit_margin, PrettyPrint.first_column_width + (i-2) * PrettyPrint.column_width + PrettyPrint.limit_margin, PrettyPrint.first_column_width + i * PrettyPrint.column_width - PrettyPrint.limit_margin) if self.mat[3][i] == "0" then PrettyPrint.PrettyPrint(self.drawables, PrettyPrint.string_matrix("0"), PrettyPrint.second_line_height, PrettyPrint.third_line_height, PrettyPrint.first_column_width + (i-2) * PrettyPrint.column_width, PrettyPrint.first_column_width + i * PrettyPrint.column_width) elseif self.mat[3][i] == "\""..string.uchar(8741).."\"" then --double vertical bar, forbidden value for the function --in this case, the limit is not pretty printed (string) local space = (PrettyPrint.fourth_line_height - PrettyPrint.third_line_height - PrettyPrint.max_size) / 2 - 4 self.drawables:add_line(PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width + 2, PrettyPrint.second_line_height , PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width + 2, PrettyPrint.third_line_height + space) self.drawables:add_line(PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width , PrettyPrint.third_line_height , PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width , PrettyPrint.third_line_height + space) self.drawables:add_line(PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width + 2, PrettyPrint.fourth_line_height - space, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width + 2, PrettyPrint.fourth_line_height) self.drawables:add_line(PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width , PrettyPrint.fourth_line_height - space, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width , PrettyPrint.fourth_line_height) elseif self.mat[3][i] == "\"||\"" then --forbidden value for the derivate self.drawables:add_line(PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width + 2, PrettyPrint.second_line_height, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width + 2, PrettyPrint.third_line_height) end if i > 2 and self.mat[1][i + 1] then self.drawables:add_line(PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width, PrettyPrint.second_line_height, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width, PrettyPrint.third_line_height) end else --draw the arrow and the sign of the derivate if self.mat[4][i] == "/'" then self.drawables:add_arrow(PrettyPrint.first_column_width + (i-2)* PrettyPrint.column_width + PrettyPrint.arrow_h_margin, PrettyPrint.fourth_line_height - PrettyPrint.arrow_v_margin, PrettyPrint.first_column_width + i * PrettyPrint.column_width - PrettyPrint.arrow_h_margin, PrettyPrint.third_line_height + PrettyPrint.arrow_v_margin) elseif self.mat[4][i] == string.uchar(8594) then self.drawables:add_arrow(PrettyPrint.first_column_width + (i-2)* PrettyPrint.column_width + PrettyPrint.arrow_h_margin, (PrettyPrint.third_line_height + PrettyPrint.fourth_line_height) / 2, PrettyPrint.first_column_width + i * PrettyPrint.column_width - PrettyPrint.arrow_h_margin, (PrettyPrint.third_line_height + PrettyPrint.fourth_line_height) / 2) elseif self.mat[4][i] == "\\"..string.uchar(184) then self.drawables:add_arrow(PrettyPrint.first_column_width + (i-2)* PrettyPrint.column_width + PrettyPrint.arrow_h_margin, PrettyPrint.third_line_height + PrettyPrint.arrow_v_margin, PrettyPrint.first_column_width + i * PrettyPrint.column_width - PrettyPrint.arrow_h_margin, PrettyPrint.fourth_line_height - PrettyPrint.arrow_v_margin) else --unknown variation, just display the string PrettyPrint.PrettyPrint(self.drawables, PrettyPrint.string_matrix(self.mat[4][i]), PrettyPrint.third_line_height, PrettyPrint.fourth_line_height, PrettyPrint.first_column_width + (i-2)* PrettyPrint.column_width, PrettyPrint.first_column_width + i * PrettyPrint.column_width) end PrettyPrint.PrettyPrint(self.drawables, PrettyPrint.string_matrix(self.mat[3][i]), PrettyPrint.second_line_height, PrettyPrint.third_line_height, PrettyPrint.first_column_width + (i-2) * PrettyPrint.column_width, PrettyPrint.first_column_width + i * PrettyPrint.column_width) end i = i + 1 end self.drawables:add_line(0, PrettyPrint.first_line_height, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width, PrettyPrint.first_line_height) self.drawables:add_line(0, PrettyPrint.second_line_height, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width, PrettyPrint.second_line_height) self.drawables:add_line(0, PrettyPrint.third_line_height, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width, PrettyPrint.third_line_height) self.drawables:add_line(0, PrettyPrint.fourth_line_height, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width, PrettyPrint.fourth_line_height) self.drawables:add_line(PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width, PrettyPrint.first_line_height, PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width, PrettyPrint.fourth_line_height) self.width = PrettyPrint.first_column_width + (i-1) * PrettyPrint.column_width local fct_matrix = PrettyPrint.get_fct_matrix() PrettyPrint.PrettyPrint(self.drawables, fct_matrix, 0, PrettyPrint.first_line_height, 0, self.width) local fx_matrix = PrettyPrint.string_matrix("f:"..self.var..string.uchar(0x21A6)) local fx_right = (self.width - fct_matrix[5][1]) / 2 PrettyPrint.PrettyPrint(self.drawables, fx_matrix, 0, PrettyPrint.first_line_height, fx_right - PrettyPrint.get_width(fx_matrix, 1, "", PrettyPrint.max_size), fx_right) self.scale = math.max(1, self:min_scale()) self.lastMousePos = {platform.window:width() / 2, platform.window:height() / 2} platform.window:invalidate() end function Table:draw(gc) gc:setColorRGB(0, 0, 0) for i = 1, self.drawables.numlines do a = self.drawables.lines[i] gc:drawLine(self.xoffset + self.scale * a[1], self.yoffset + self.scale * a[2], self.xoffset + self.scale * a[3], self.yoffset + self.scale * a[4]) end for i = 1, self.drawables.numtexts do a = self.drawables.texts[i] gc:setFont("sansserif", "r", math.min(self.scale * a[5], 12)) gc:drawString(a[1], self.xoffset + self.scale * a[2], self.yoffset + self.scale * a[3], a[4]) end end function Table:is_out(direction) if direction == "down" then if self.yoffset + self.height * self.scale < platform.window:height() and self.yoffset < 0 then return true end return false elseif direction == "up" then if self.yoffset + self.height * self.scale > platform.window:height() and self.yoffset > 0 then return true end return false elseif direction == "left" then if self.xoffset + self.width * self.scale > platform.window:width() and self.xoffset > 0 then return true end return false elseif direction == "right" then if self.xoffset + self.width * self.scale < platform.window:width() and self.xoffset < 0 then return true end return false end end function Table:min_scale() -- min scale is given by the limit of 6 for the ont size local m = PrettyPrint.max_size for i = 1, self.drawables.numtexts do m = math.min(m, self.drawables.texts[i][5]) end return 6.1 / m end function Table:zoom_out() if self.scale / 1.15 >= self:min_scale() then self.scale = self.scale / 1.15 self.xoffset = self.xoffset / 1.15 self.yoffset = self.yoffset / 1.15 end end function Table:max_scale() return 3 + self:min_scale() end function Table:zoom_in() if self.scale * 1.15 <= self:max_scale() then self.scale = self.scale * 1.15 self.xoffset = self.xoffset * 1.15 self.yoffset = self.yoffset * 1.15 end end m_table = Table() -------------------------------------------------------------------------------- -- Events handling -------------------------------------------------------------------------------- function on.create() var.monitor("luarep.signal") end function on.paint(gc) m_table:draw(gc) end function on.arrowUp() m_table.yoffset = m_table.yoffset + 6 * m_table.scale if m_table:is_out("up") then m_table.yoffset = m_table.yoffset - 6 * m_table.scale end platform.window:invalidate() end function on.arrowDown() m_table.yoffset = m_table.yoffset - 6 * m_table.scale if m_table:is_out("down") then m_table.yoffset = m_table.yoffset + 6 * m_table.scale end platform.window:invalidate() end function on.arrowLeft() m_table.xoffset = m_table.xoffset + 6 * m_table.scale if m_table:is_out("left") then m_table.xoffset = m_table.xoffset - 6 * m_table.scale end platform.window:invalidate() end function on.arrowRight() m_table.xoffset = m_table.xoffset - 6 * m_table.scale if m_table:is_out("right") then m_table.xoffset = m_table.xoffset + 6 * m_table.scale end platform.window:invalidate() end function on.mouseMove(x, y) xx = x - m_table.lastMousePos[1] yy = y - m_table.lastMousePos[2] if math.max(math.abs(xx), math.abs(yy)) <= 4 then m_table.yoffset = m_table.yoffset - yy * m_table.scale * 1.5 if (yy > 0 and m_table:is_out("down")) or (yy < 0 and m_table:is_out("up")) then m_table.yoffset = m_table.yoffset + yy * m_table.scale * 1.5 end m_table.xoffset = m_table.xoffset - xx * m_table.scale * 1.5 if (xx > 0 and m_table:is_out("right")) or (xx < 0 and m_table:is_out("left")) then m_table.xoffset = m_table.xoffset + xx * m_table.scale * 1.5 end platform.window:invalidate() end m_table.lastMousePos = {x, y} end function on.charIn(ch) if ch == "*" then m_table:zoom_in() elseif ch == "/" then m_table:zoom_out() end platform.window:invalidate() end function on.varChange(varlist) for _, v in ipairs(varlist) do if type(var.recall(v)) == "nil" then return -3 elseif v == "luarep.signal" then m_table:calculate() platform.window:invalidate() return 0 end end end