integrate NagView
This commit is contained in:
parent
d01ee8d2f4
commit
c0ad86de8c
|
@ -7,6 +7,7 @@ local keymap
|
||||||
local RootView
|
local RootView
|
||||||
local StatusView
|
local StatusView
|
||||||
local CommandView
|
local CommandView
|
||||||
|
local NagView
|
||||||
local DocView
|
local DocView
|
||||||
local Doc
|
local Doc
|
||||||
|
|
||||||
|
@ -350,6 +351,7 @@ function core.init()
|
||||||
RootView = require "core.rootview"
|
RootView = require "core.rootview"
|
||||||
StatusView = require "core.statusview"
|
StatusView = require "core.statusview"
|
||||||
CommandView = require "core.commandview"
|
CommandView = require "core.commandview"
|
||||||
|
NagView = require "core.nagview"
|
||||||
DocView = require "core.docview"
|
DocView = require "core.docview"
|
||||||
Doc = require "core.doc"
|
Doc = require "core.doc"
|
||||||
|
|
||||||
|
@ -418,9 +420,12 @@ function core.init()
|
||||||
core.root_view = RootView()
|
core.root_view = RootView()
|
||||||
core.command_view = CommandView()
|
core.command_view = CommandView()
|
||||||
core.status_view = StatusView()
|
core.status_view = StatusView()
|
||||||
|
core.nag_view = NagView()
|
||||||
|
|
||||||
local cur_node = core.root_view.root_node
|
local cur_node = core.root_view.root_node
|
||||||
cur_node.is_primary_node = true
|
cur_node.is_primary_node = true
|
||||||
|
cur_node:split("up", core.nag_view, {y = true})
|
||||||
|
cur_node = cur_node.b
|
||||||
cur_node = cur_node:split("down", core.command_view, {y = true})
|
cur_node = cur_node:split("down", core.command_view, {y = true})
|
||||||
cur_node = cur_node:split("down", core.status_view, {y = true})
|
cur_node = cur_node:split("down", core.status_view, {y = true})
|
||||||
|
|
||||||
|
@ -449,7 +454,7 @@ function core.init()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function core.confirm_close_all()
|
function core.confirm_close_all(close_fn, ...)
|
||||||
local dirty_count = 0
|
local dirty_count = 0
|
||||||
local dirty_name
|
local dirty_name
|
||||||
for _, doc in ipairs(core.docs) do
|
for _, doc in ipairs(core.docs) do
|
||||||
|
@ -465,10 +470,17 @@ function core.confirm_close_all()
|
||||||
else
|
else
|
||||||
text = string.format("%d docs have unsaved changes. Quit anyway?", dirty_count)
|
text = string.format("%d docs have unsaved changes. Quit anyway?", dirty_count)
|
||||||
end
|
end
|
||||||
local confirm = system.show_confirm_dialog("Unsaved Changes", text)
|
local args = {...}
|
||||||
if not confirm then return false end
|
local opt = {
|
||||||
|
{ font = style.font, text = "Yes" },
|
||||||
|
{ font = style.font, text = "No" }
|
||||||
|
}
|
||||||
|
core.nag_view:show("Unsaved Changes", text, opt, function(item)
|
||||||
|
if item.text == "Yes" then close_fn(table.unpack(args)) end
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
close_fn(...)
|
||||||
end
|
end
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local temp_uid = (system.get_time() * 1000) % 0xffffffff
|
local temp_uid = (system.get_time() * 1000) % 0xffffffff
|
||||||
|
@ -517,9 +529,7 @@ local function quit_with_function(quit_fn, force)
|
||||||
save_session()
|
save_session()
|
||||||
quit_fn()
|
quit_fn()
|
||||||
else
|
else
|
||||||
if core.confirm_close_all() then
|
core.confirm_close_all(quit_with_function, quit_fn, true)
|
||||||
quit_with_function(quit_fn, true)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -595,6 +605,7 @@ end
|
||||||
|
|
||||||
function core.set_active_view(view)
|
function core.set_active_view(view)
|
||||||
assert(view, "Tried to set active view to nil")
|
assert(view, "Tried to set active view to nil")
|
||||||
|
if core.active_view and core.active_view.force_focus then return end
|
||||||
if view ~= core.active_view then
|
if view ~= core.active_view then
|
||||||
if view.doc and view.doc.filename then
|
if view.doc and view.doc.filename then
|
||||||
core.set_visited(view.doc.filename)
|
core.set_visited(view.doc.filename)
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
local core = require "core"
|
||||||
|
local config = require "core.config"
|
||||||
|
local common = require "core.common"
|
||||||
|
local View = require "core.view"
|
||||||
|
local style = require "core.style"
|
||||||
|
|
||||||
|
local BORDER_WIDTH = common.round(2 * SCALE)
|
||||||
|
local BORDER_PADDING = common.round(5 * SCALE)
|
||||||
|
|
||||||
|
local noop = function() end
|
||||||
|
|
||||||
|
local NagView = View:extend()
|
||||||
|
|
||||||
|
function NagView:new()
|
||||||
|
NagView.super.new(self)
|
||||||
|
self.size.y = 0
|
||||||
|
self.force_focus = false
|
||||||
|
self.title = "Warning"
|
||||||
|
self.message = ""
|
||||||
|
self.options = {}
|
||||||
|
self.submit = noop
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:get_title()
|
||||||
|
return self.title
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:each_option()
|
||||||
|
return coroutine.wrap(function()
|
||||||
|
for i = #self.options, 1, -1 do
|
||||||
|
coroutine.yield(i, self.options[i])
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:get_options_height()
|
||||||
|
local max = 0
|
||||||
|
for _, opt in ipairs(self.options) do
|
||||||
|
local lh = style.font:get_height(opt.text)
|
||||||
|
if lh > max then max = lh end
|
||||||
|
end
|
||||||
|
return max
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:get_line_height()
|
||||||
|
local maxlh = math.max(style.font:get_height(self.message), self:get_options_height())
|
||||||
|
return 2 * BORDER_WIDTH + 2 * BORDER_PADDING + maxlh + 2 * style.padding.y
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:update()
|
||||||
|
NagView.super.update(self)
|
||||||
|
|
||||||
|
local dest = core.active_view == self and self:get_line_height() or 0
|
||||||
|
self:move_towards(self.size, "y", dest)
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:draw_overlay()
|
||||||
|
local ox, oy = self:get_content_offset()
|
||||||
|
oy = oy + self.size.y
|
||||||
|
local w, h = core.root_view.size.x, core.root_view.size.y - oy
|
||||||
|
core.root_view:defer_draw(function()
|
||||||
|
renderer.draw_rect(ox, oy, w, h, style.nagbar_dim)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:each_visible_option()
|
||||||
|
return coroutine.wrap(function()
|
||||||
|
local halfh = math.floor(self.size.y / 2)
|
||||||
|
local ox, oy = self:get_content_offset()
|
||||||
|
ox = ox + self.size.x - style.padding.x
|
||||||
|
|
||||||
|
for i, opt in self:each_option() do
|
||||||
|
local lw, lh = opt.font:get_width(opt.text), opt.font:get_height(opt.text)
|
||||||
|
local bw, bh = (lw + 2 * BORDER_WIDTH + 2 * BORDER_PADDING), (lh + 2 * BORDER_WIDTH + 2 * BORDER_PADDING)
|
||||||
|
local halfbh = math.floor(bh / 2)
|
||||||
|
local bx, by = math.max(0, ox - bw), math.max(0, oy + halfh - halfbh)
|
||||||
|
local fw, fh = bw - 2 * BORDER_WIDTH, bh - 2 * BORDER_WIDTH
|
||||||
|
local fx, fy = bx + BORDER_WIDTH, by + BORDER_WIDTH
|
||||||
|
coroutine.yield(i, opt, bx,by,bw,bh, fx,fy,fw,fh)
|
||||||
|
ox = ox - bw - style.padding.x
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:on_mouse_moved(mx, my, ...)
|
||||||
|
NagView.super.on_mouse_moved(self, mx, my, ...)
|
||||||
|
local selected = false
|
||||||
|
for i, _, x,y,w,h in self:each_visible_option() do
|
||||||
|
if mx >= x and my >= y and mx < x + w and my < y + h then
|
||||||
|
self.selected = i
|
||||||
|
selected = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not selected then self.selected = nil end
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:on_mouse_pressed(...)
|
||||||
|
if not NagView.super.on_mouse_pressed(self, ...) and self.selected then
|
||||||
|
self.force_focus = false
|
||||||
|
core.set_active_view(core.last_active_view)
|
||||||
|
self.submit(self.options[self.selected])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:draw()
|
||||||
|
if self.size.y <= 0 then return end
|
||||||
|
|
||||||
|
self:draw_overlay()
|
||||||
|
self:draw_background(style.nagbar)
|
||||||
|
|
||||||
|
-- draw message
|
||||||
|
local ox, oy = self:get_content_offset()
|
||||||
|
common.draw_text(style.font, style.nagbar_text, self.message, "left", ox + style.padding.x, oy, self.size.x, self.size.y)
|
||||||
|
|
||||||
|
-- draw buttons
|
||||||
|
for i, opt, bx,by,bw,bh, fx,fy,fw,fh in self:each_visible_option() do
|
||||||
|
local fill = i == self.selected and style.nagbar_text or style.nagbar
|
||||||
|
local text_color = i == self.selected and style.nagbar or style.nagbar_text
|
||||||
|
|
||||||
|
renderer.draw_rect(bx,by,bw,bh, style.nagbar_text)
|
||||||
|
|
||||||
|
if i ~= self.selected then
|
||||||
|
renderer.draw_rect(fx,fy,fw,fh, fill)
|
||||||
|
end
|
||||||
|
|
||||||
|
common.draw_text(opt.font, text_color, opt.text, "center", fx,fy,fw,fh)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function NagView:show(title, message, options, on_select, on_cancel)
|
||||||
|
self.title = title or "Warning"
|
||||||
|
self.message = message or "Empty?"
|
||||||
|
self.options = options or {}
|
||||||
|
if on_cancel then table.insert(options, { key = "cancel", font = style.icon_font, text = "C" }) end
|
||||||
|
self.force_focus = true
|
||||||
|
self.submit = function(item)
|
||||||
|
self.submit = noop -- reset the submit function
|
||||||
|
if item.key == "cancel" and on_cancel then
|
||||||
|
on_cancel()
|
||||||
|
elseif on_select then
|
||||||
|
on_select(item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
core.set_active_view(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
return NagView
|
|
@ -5,6 +5,7 @@ local keymap = require "core.keymap"
|
||||||
local Object = require "core.object"
|
local Object = require "core.object"
|
||||||
local View = require "core.view"
|
local View = require "core.view"
|
||||||
local CommandView = require "core.commandview"
|
local CommandView = require "core.commandview"
|
||||||
|
local NagView = require "core.nagview"
|
||||||
local DocView = require "core.docview"
|
local DocView = require "core.docview"
|
||||||
|
|
||||||
|
|
||||||
|
@ -622,6 +623,12 @@ end
|
||||||
|
|
||||||
|
|
||||||
function RootView:on_mouse_moved(x, y, dx, dy)
|
function RootView:on_mouse_moved(x, y, dx, dy)
|
||||||
|
if core.active_view == core.nag_view then
|
||||||
|
system.set_cursor("arrow")
|
||||||
|
core.active_view:on_mouse_moved(x, y, dx, dy)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if self.dragged_divider then
|
if self.dragged_divider then
|
||||||
local node = self.dragged_divider
|
local node = self.dragged_divider
|
||||||
if node.type == "hsplit" then
|
if node.type == "hsplit" then
|
||||||
|
|
|
@ -41,6 +41,9 @@ style.line_number2 = { common.color "#83838f" }
|
||||||
style.line_highlight = { common.color "#343438" }
|
style.line_highlight = { common.color "#343438" }
|
||||||
style.scrollbar = { common.color "#414146" }
|
style.scrollbar = { common.color "#414146" }
|
||||||
style.scrollbar2 = { common.color "#4b4b52" }
|
style.scrollbar2 = { common.color "#4b4b52" }
|
||||||
|
style.nagbar = { common.color "#FF0000" }
|
||||||
|
style.nagbar_text = { common.color "#FFFFFF" }
|
||||||
|
style.nagbar_dim = { common.color "rgba(0, 0, 0, 0.45)" }
|
||||||
|
|
||||||
style.syntax = {}
|
style.syntax = {}
|
||||||
style.syntax["normal"] = { common.color "#e1e1e6" }
|
style.syntax["normal"] = { common.color "#e1e1e6" }
|
||||||
|
|
Loading…
Reference in New Issue