2
0
mirror of https://github.com/koreader/koreader synced 2024-11-16 06:12:56 +00:00
koreader/frontend/ui/widget/naturallightwidget.lua
NiLuJe df0bbc9db7
Tame some ButtonTable users into re-using Buttontable instances if possible (#7166)
* QuickDictLookup, ImageViewer, NumberPicker: Smarter `update` that will re-use most of the widget's layout instead of re-instantiating all the things.
* SpinWidget/DoubleSpinWidget: The NumberPicker change above renders a hack to preserve alpha on these widgets almost unnecessary. Also fixed said hack to also apply to the center, value button.

* Button: Don't re-instantiate the frame in setText/setIcon when unnecessary (e.g., no change at all, or no layout change).
* Button: Add a refresh method that repaints and refreshes a *specific* Button (provided it's been painted once) all on its lonesome.

* ConfigDialog: Free everything that's going to be re-instatiated on update
 
* A few more post #7118 fixes:
  * SkimTo: Always flag the chapter nav buttons as vsync
  * Button: Fix the highlight on rounded buttons when vsync is enabled (e.g., it's now entirely visible, instead of showing a weird inverted corner glitch).
  * Some more heuristic tweaks in Menu/TouchMenu/Button/IconButton
* ButtonTable: fix the annoying rounding issue I'd noticed in #7054 ;).

* Enable dithering in TextBoxWidget (e.g., in the Wikipedia full view). This involved moving the HW dithering align fixup to base, where it always ought to have been ;).

* Switch a few widgets that were using "partial" on close to "ui", or, more rarely, "flashui". The intent being to limit "partial" purely to the Reader, because it has a latency cost when mixed with other refreshes, which happens often enough in UI ;).

* Minor documentation tweaks around UIManager's `setDirty` to reflect that change.

* ReaderFooter: Force a footer repaint on resume if it is visible (otherwise, just update it).
* ReaderBookmark: In the same vein, don't repaint an invisible footer on bookmark count changes.
2021-01-29 00:20:15 +01:00

434 lines
14 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local Blitbuffer = require("ffi/blitbuffer")
local Button = require("ui/widget/button")
local CenterContainer = require("ui/widget/container/centercontainer")
local Device = require("device")
local Font = require("ui/font")
local FrameContainer = require("ui/widget/container/framecontainer")
local Geom = require("ui/geometry")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan")
local InputContainer = require("ui/widget/container/inputcontainer")
local InputText = require("ui/widget/inputtext")
local LineWidget = require("ui/widget/linewidget")
local OverlapGroup = require("ui/widget/overlapgroup")
local Size = require("ui/size")
local TextBoxWidget = require("ui/widget/textboxwidget")
local TextWidget = require("ui/widget/textwidget")
local UIManager = require("ui/uimanager")
local VerticalGroup = require("ui/widget/verticalgroup")
local VerticalSpan = require("ui/widget/verticalspan")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local _ = require("gettext")
local Screen = Device.screen
local NaturalLightWidget = InputContainer:new{
is_always_active = true,
title_face = Font:getFace("x_smalltfont"),
width = nil,
height = nil,
textbox_width = 0.1,
button_width = 0.07,
text_width = 0.3,
white_gain = nil,
white_offset = nil,
red_gain = nil,
red_offset = nil,
green_gain = nil,
green_offset = nil,
exponent = nil,
fl_widget = nil,
old_values = nil
}
function NaturalLightWidget:init()
self.medium_font_face = Font:getFace("ffont")
self.nl_bar = {}
self.screen_width = Screen:getWidth()
self.screen_height = Screen:getHeight()
self.span = math.ceil(self.screen_height * 0.01)
self.width = math.floor(self.screen_width * 0.95)
self.button_width = 0.08 * self.width
self.textbox_width = 0.1 * self.width
self.text_width = 0.2 * self.width
self.powerd = Device:getPowerDevice()
self:createFrame()
end
function NaturalLightWidget:applyValues()
self.powerd.fl.white_gain = self.white_gain[2]:getText()
self.powerd.fl.white_offset = self.white_offset[2]:getText()
self.powerd.fl.red_gain = self.red_gain[2]:getText()
self.powerd.fl.red_offset = self.red_offset[2]:getText()
self.powerd.fl.green_gain = self.green_gain[2]:getText()
self.powerd.fl.green_offset = self.green_offset[2]:getText()
self.powerd.fl.exponent = self.exponent[2]:getText()
self.powerd.fl:setNaturalBrightness()
end
-- Create an InputText with '-' and '+' button next to it. Tapping
-- those buttons will de/increase by 'step', and 'step/10' on hold.
function NaturalLightWidget:adaptableNumber(initial, step)
local minus_number_plus = HorizontalGroup:new{ align = "center" }
local input_text = InputText:new{
parent = self,
text = initial,
input_type = "number",
hint = "",
width = self.textbox_width,
enter_callback = function()
self:closeKeyboard()
self:applyValues()
UIManager:setDirty(self._current_input, "fast")
end
}
input_text:unfocus()
local button_minus = Button:new{
text = "",
margin = Size.margin.small,
radius = 0,
width = self.button_width,
show_parent = self,
callback = function()
self:closeKeyboard()
self:setValueTextBox(input_text, input_text:getText() - step)
self:applyValues()
end,
hold_callback = function()
self:closeKeyboard()
self:setValueTextBox(input_text, input_text:getText() - step/10.0)
self:applyValues()
end,
}
local button_plus = Button:new{
text = "",
margin = Size.margin.small,
radius = 0,
width = self.button_width,
show_parent = self,
callback = function()
self:closeKeyboard()
self:setValueTextBox(input_text, input_text:getText() + step)
self:applyValues()
end,
hold_callback = function()
self:closeKeyboard()
self:setValueTextBox(input_text, input_text:getText() + step/10)
self:applyValues()
end,
}
table.insert(minus_number_plus, button_minus)
table.insert(minus_number_plus, input_text)
table.insert(minus_number_plus, button_plus)
return minus_number_plus
end
-- Get current values that are used in sysfs_light
function NaturalLightWidget:getCurrentValues()
return {white_gain =
self.powerd.fl.white_gain,
white_offset =
self.powerd.fl.white_offset,
red_gain =
self.powerd.fl.red_gain,
red_offset =
self.powerd.fl.red_offset,
green_gain =
self.powerd.fl.green_gain,
green_offset =
self.powerd.fl.green_offset,
exponent =
self.powerd.fl.exponent}
end
function NaturalLightWidget:createFrame()
self.nl_title = FrameContainer:new{
padding = Size.padding.default,
margin = Size.margin.title,
bordersize = 0,
TextWidget:new{
text = _("Natural light configuration"),
face = self.title_face,
bold = true,
width = math.floor(self.screen_width * 0.95),
},
}
local main_content = FrameContainer:new{
padding = Size.padding.button,
margin = Size.margin.small,
bordersize = 0,
self:createMainContent(math.floor(self.screen_width * 0.95),
math.floor(self.screen_height * 0.2))
}
local nl_line = LineWidget:new{
dimen = Geom:new{
w = self.width,
h = Size.line.thick,
}
}
self.nl_bar = OverlapGroup:new{
dimen = {
w = self.width,
h = self.nl_title:getSize().h
},
self.nl_title,
}
self.nl_frame = FrameContainer:new{
radius = Size.radius.window,
bordersize = Size.border.window,
padding = 0,
margin = 0,
background = Blitbuffer.COLOR_WHITE,
VerticalGroup:new{
align = "left",
self.nl_bar,
nl_line,
CenterContainer:new{
dimen = Geom:new{
w = nl_line:getSize().w,
h = main_content:getSize().h,
},
main_content,
},
}
}
self[1] = WidgetContainer:new{
align = "top",
dimen =Geom:new{
x = 0, y = 0,
w = self.screen_width,
h = self.screen_height,
},
FrameContainer:new{
bordersize = 0,
self.nl_frame,
}
}
end
function NaturalLightWidget:createMainContent(width, height)
self.fl_container = CenterContainer:new{
dimen = Geom:new{ w = width, h = height },
}
self.white_gain = self:adaptableNumber(self.powerd.fl.white_gain, 1)
self.white_offset = self:adaptableNumber(self.powerd.fl.white_offset, 1)
self.red_gain = self:adaptableNumber(self.powerd.fl.red_gain, 1)
self.red_offset = self:adaptableNumber(self.powerd.fl.red_offset, 1)
self.green_gain = self:adaptableNumber(self.powerd.fl.green_gain, 1)
self.green_offset = self:adaptableNumber(self.powerd.fl.green_offset, 1)
self.exponent = self:adaptableNumber(self.powerd.fl.exponent, 0.1)
local separator = HorizontalSpan:new{ width = Size.span.horizontal_default }
local vspan = VerticalSpan:new{ width = Size.span.vertical_large * 2}
local vertical_group = VerticalGroup:new{ align = "center" }
local title_group = HorizontalGroup:new{ align = "center" }
local white_group = HorizontalGroup:new{ align = "center" }
local red_group = HorizontalGroup:new{ align = "center" }
local green_group = HorizontalGroup:new{ align = "center" }
local exponent_group = HorizontalGroup:new{ align = "center" }
local button_group = HorizontalGroup:new{ align = "center" }
local text_gain = TextBoxWidget:new{
text = _("Amplification"),
face = self.medium_font_face,
bold = true,
alignment = "left",
width = self.textbox_width + 2 * self.button_width
}
local text_offset = TextBoxWidget:new{
text = _("Offset"),
face = self.medium_font_face,
bold = true,
alignment = "left",
width = self.textbox_width + self.button_width
}
local text_white = TextBoxWidget:new{
text = _("White"),
face = self.medium_font_face,
bold = true,
alignment = "left",
width = self.text_width
}
local text_red = TextBoxWidget:new{
text = _("Red"),
face = self.medium_font_face,
bold = true,
alignment = "left",
width = self.text_width
}
local text_green = TextBoxWidget:new{
text = _("Green"),
face = self.medium_font_face,
bold = true,
alignment = "left",
width = self.text_width
}
local text_exponent = TextBoxWidget:new{
text = _("Exponent"),
face = self.medium_font_face,
bold = true,
alignment = "left",
width = self.text_width
}
local button_defaults = Button:new{
text = "Restore Defaults",
margin = Size.margin.small,
radius = 0,
width = math.floor(self.width * 0.35),
show_parent = self,
callback = function()
self:setAllValues({white_gain = 25,
white_offset = -25,
red_gain = 24,
red_offset = 0,
green_gain = 24,
green_offset = -65,
exponent = 0.25})
end,
}
local button_cancel = Button:new{
text = "Cancel",
margin = Size.margin.small,
radius = 0,
width = math.floor(self.width * 0.2),
show_parent = self,
callback = function()
self:setAllValues(self.old_values)
self:onClose()
end,
}
local button_ok = Button:new{
text = "Save",
margin = Size.margin.small,
radius = 0,
width = math.floor(self.width * 0.2),
show_parent = self,
callback = function()
G_reader_settings:saveSetting("natural_light_config",
self:getCurrentValues())
self:onClose()
end,
}
table.insert(title_group, HorizontalSpan:new{
width = self.text_width + self.button_width
})
table.insert(title_group, text_gain)
table.insert(title_group, separator)
table.insert(title_group, HorizontalSpan:new{
width = self.button_width
})
table.insert(title_group, text_offset)
table.insert(white_group, text_white)
table.insert(white_group, self.white_gain)
table.insert(white_group, separator)
table.insert(white_group, self.white_offset)
table.insert(red_group, text_red)
table.insert(red_group, self.red_gain)
table.insert(red_group, separator)
table.insert(red_group, self.red_offset)
table.insert(green_group, text_green)
table.insert(green_group, self.green_gain)
table.insert(green_group, separator)
table.insert(green_group, self.green_offset)
table.insert(exponent_group, text_exponent)
table.insert(exponent_group, self.exponent)
table.insert(button_group, button_defaults)
table.insert(button_group, HorizontalSpan:new{
width = 0.05*self.width
})
table.insert(button_group, button_cancel)
table.insert(button_group, button_ok)
table.insert(vertical_group, title_group)
table.insert(vertical_group, white_group)
table.insert(vertical_group, red_group)
table.insert(vertical_group, green_group)
table.insert(vertical_group, vspan)
table.insert(vertical_group, exponent_group)
table.insert(vertical_group, vspan)
table.insert(vertical_group, button_group)
table.insert(self.fl_container, vertical_group)
-- Reset container height to what it actually contains
self.fl_container.dimen.h = vertical_group:getSize().h
UIManager:setDirty(self, "ui")
return self.fl_container
end
function NaturalLightWidget:setAllValues(values)
self:setValueTextBox(self.white_gain[2], values.white_gain)
self:setValueTextBox(self.white_offset[2], values.white_offset)
self:setValueTextBox(self.red_gain[2], values.red_gain)
self:setValueTextBox(self.red_offset[2], values.red_offset)
self:setValueTextBox(self.green_gain[2], values.green_gain)
self:setValueTextBox(self.green_offset[2], values.green_offset)
self:setValueTextBox(self.exponent[2], values.exponent)
self:applyValues()
end
function NaturalLightWidget:setValueTextBox(widget, val)
widget:focus()
widget:setText(val)
widget:unfocus()
end
function NaturalLightWidget:onCloseWidget()
self:closeKeyboard()
UIManager:setDirty(nil, function()
return "flashui", self.nl_frame.dimen
end)
-- Tell frontlight widget that we're closed
self.fl_widget:naturalLightConfigClose()
return true
end
function NaturalLightWidget:onShow()
UIManager:setDirty(self, function()
return "ui", self.nl_frame.dimen
end)
-- Tell the frontlight widget that we're open
self.fl_widget:naturalLightConfigOpen()
-- Store values in case user cancels
self.old_values = self:getCurrentValues()
return true
end
function NaturalLightWidget:onClose()
UIManager:close(self)
return true
end
function NaturalLightWidget:onShowKeyboard()
if self._current_input then
self._current_input:onShowKeyboard()
self._current_input:focus()
end
end
function NaturalLightWidget:onCloseKeyboard()
if self._current_input then
self._current_input:onCloseKeyboard()
self._current_input:unfocus()
-- Make sure the cursor is deleted
UIManager:setDirty(self._current_input, "fast")
end
end
function NaturalLightWidget:onSwitchFocus(inputbox)
self:onCloseKeyboard()
self._current_input = inputbox
self:applyValues()
self:onShowKeyboard()
end
function NaturalLightWidget:closeKeyboard()
if self._current_input then
self._current_input:onCloseKeyboard()
self._current_input:unfocus()
end
end
return NaturalLightWidget