local Window = require("window") local ui = require("ui") local Widget = require("widget") local font = text.loadfont("Victoria.8b.gif") local win = nil local color = { gray = 0, black = 1, white = 2, aqua = 3, red = 4, green = 5, blue = 6, blown = 7 } local Select = Widget:extend() do function Select:constructor(title, data, max_items) local m, c = view.screenmode() self.doredraw = false self.data = data self.clicked = false self.unclicked = false self.pressed = false self.unpressed = false self.max_items = max_items -- how many items can be displayed inside window self.button_height = 1 self.opened = true self.selected = m+1 self.scrolly = 0 self.scrollymax = 1 self.fontw = 8 self.fonth = 4 -- triangle images -- local by, bx -- self.triup = image.new(8, 8, c) -- self.tridown = image.new(8, 8, c) -- for by = 0, 8 do -- for bx = by+1, 8 do -- image.pixel(self.tridown, bx - by / 2, by-2, color.white) -- image.pixel(self.triup, bx - by / 2, 8 - by-2, color.black) -- end -- end Widget:constructor(title) end -- check someting every step function Select:step(t) -- if t % 3 == 0 then -- -- end local prevvp = view.active() local doredraw = false view.active(self.container) local vw, vh = view.size(self.container) local mx, my, mb = input.mouse() self.scrollymax = vh - self.fonth * 2 if mb == 1 then if self.unpressed then self.clicked = true self.pressed = true end else self.pressed = false end if not self.pressed and not self.unpressed then self.unclicked = true end -- handle events if self.pressed then if self.onpress then self:onpress() end end if self.unpressed then if self.onunpress then self:onunpress() end end if self.clicked then self.doredraw = true if self.onclick then self:onclick() end end if self.unclicked then self.doredraw = true if self.onunclick then self:onunclick() end end -- redraw if needed if self.doredraw then self:redraw(t) end view.active(prevvp) self.clicked = false self.unclicked = false self.unpressed = not self.pressed end function Select:onclick() local vw, vh = view.size(self.container) local mx, my, mb = input.mouse() local th = self.fonth if mx > vw - 16 and my > 0 and mx <= vw and my <= th then -- print("on click event") self.opened = not self.opened self.scrolly = 0 else if mx > 0 and my > th and mx <= vw and my <= vh then for i = 1, self.max_items do if mx > 0 and my > i * th and mx <= vw - 16 and my <= i * th + th then self.selected = self:getScrollIndex() + i break end end end end -- print("on click event") end function Select:onunclick() -- print("on unclick event") end function Select:onpress() local vw, vh = view.size(self.container) local mx, my = input.mouse() local th = self.fonth if mx > vw - 16 and my > th and mx <= vw and my <= vh then self.doredraw = true self.scrolly = math.min(vh - th * 2, math.max(my - th - th / 2, 0)) end -- print("on press event") end function Select:onunpress() -- print("on unpress event") end function Select:getScrollIndex() local i = math.floor(self.scrolly / self.scrollymax * (#self.data - self.max_items+2)) return math.min(i, #self.data) end -- calls on every window change (resize, move, click, etc...) function Select:redraw(t) local tw = self.fontw local th = self.fonth local prevvp = view.active() view.active(self.container) local vw, vh = view.size(self.container) gfx.bgcolor(self.bgcolor) gfx.cls() gfx.fgcolor(self.bgtextcolor) text.draw(self.label, self.font, (vw - 16) / 2 - tw / 2, th / 4) self:outset(0, 0, vw - 16, th) if self.opened then self:inset(vw - 16, 0, 16, th) -- image.draw(self.triup, vw - 16 + 4, 2, 0, 0, 8, 8) gfx.fgcolor(self.fgtextcolor) text.draw('-', self.font, vw - 8-4, 2) -- draw items local ii = self:getScrollIndex() for i = 1, self.max_items do local yy = th / 4 + i * th + 1 if self.selected == ii + i then gfx.fgcolor(self.bgtextcolor) gfx.bar(1, yy-2, vw-16, th) gfx.fgcolor(self.bgcolor) text.draw(self.data[ii + i], self.font, 4, th / 4 + i * th + 1) else gfx.fgcolor(self.fgtextcolor) text.draw(self.data[ii + i], self.font, 4, th / 4 + i * th + 1) end end -- draw select body self:outset(0, th, vw, vh - th) -- draw scroll navigation gfx.fgcolor(self.fgcolor) gfx.bar(vw - 16+1, th+1, 14, vh - th - 2) gfx.fgcolor(self.fgtextcolor) gfx.bar(vw - 16, th+1, 1, vh - th - 2) gfx.fgcolor(self.bgcolor) gfx.bar(vw - 16, th+self.scrolly, 15, vh - th*4-2) self:outset(vw - 16, th+self.scrolly, 15, vh - th*4-2) else self:outset(vw - 16, 0, 16, th) -- image.draw(self.tridown, vw - 16 + 4, 2, 0, 0, 8, 8) gfx.fgcolor(self.bgtextcolor) text.draw('-', self.font, vw - 8-4, 2) text.draw(':^)', self.font, vw / 2 - 8, vh / 2) end view.active(prevvp) end -- set size automatically (not working now) function Select:autosize(w, h) local prevvp = view.active() view.active(self.container) self.fontw, self.fonth = text.draw(self.label, self.font, view.size(view.active())) self.fonth = self.fonth * 1.25+1 local th = self.fonth local dh = math.min(self.max_items, #self.data) -- data height if not h then h = dh*th end view.active(prevvp) return self:size(w, h) end end local select_data = { "Mode 0 (80x45)", "Mode 1 (160x45)", "Mode 2 (320x45)", "Mode 3 (640x45)", "Mode 4 (80x90)", "Mode 5 (160x90)", "Mode 6 (320x90)", "Mode 7 (640x90)", "Mode 8 (80x180)", "Mode 9 (160x180)", "Mode 10 (320x180)", "Mode 11 (640x180)", "Mode 12 (80x360)", "Mode 13 (160x360)", "Mode 14 (320x360)", "Mode 15 (640x360)" } local select = Select:new("Select", select_data, 6) local confirm = ui.Button:new("Confirm") local cancel = ui.Button:new("Cancel") function _init() vieww, viewh = view.size() win = Window:new("Set Resolution", vieww / 2 - 80, viewh / 2 - 50, 170, 87) -- print("view width: "..vieww) -- print("view height: "..viewh) -- win.resizable = true win.onclose = function() sys.exit() end -- this function is not implemented in window.lua -- so I decided to make my own -- note that I dont modify the original window.lua file, for compatibility win.onresize = function() view.active(win.mainvp) gfx.cls() ww, wh = view.size(win.mainvp) -- ww = math.max(ww, 170) -- wh = math.max(wh, 86) -- win:size(ww, wh) -- print("resize event") select:autosize(ww-2, wh - 14 - 3) confirm:size(ww / 2 - 2, 14); confirm:position(1, wh - 14) cancel:size(ww / 2 - 3, 14); cancel :position(ww / 2 + 2, wh - 14) end ww, wh = view.size(win.mainvp) win:attach("select", select ); select:autosize(ww-2, wh - 14 - 3); select:position(1, 1) win:attach("confirm", confirm); confirm:size(ww / 2 - 2, 14); confirm:position(1, 59) win:attach("cancel", cancel ); cancel:size(ww / 2 - 3, 14); cancel :position(ww / 2 + 2, 59) cancel.onclick = function() sys.exit() end confirm.onclick = function() local m, c = view.screenmode() -- print('selected mode: '..select_data[select.selected]) view.screenmode(view.active(), select.selected-1, c) -- print('mode: '..select.selected-1) end sys.stepinterval(0) end function _step(t) win:step(t) -- view.active(win.mainvp) -- custom on resize event local nww, nwh = view.size(win.mainvp) if ww ~= nww or wh ~= nwh then win.onresize() end end