More app launcher improvements (#132)

* Make sure there is always a default icon

* Use get_example_icon_path to get the default icon

* Refactor scrolling to add support for left and right scrolling

* fixup! Make sure there is always a default icon

* Fix calculation happening at the wrong time

* Fix default icons again

* Where did that come from?

* Fix calculation happening at the wrong time for scroll_up as well

* Fix error on scroll right when scrolling to page where amount of rows is smaller than the selected row

* Sort search results by string similarity

* Don't sort by similarity when the search string is empty

* Add hover effects

* try_to_keep_index_after_searching should be false by default

* This should only trigger for lmb

* Add an option to hide the app launcher when clicked with lmb/rmb outside of it

* Use gtk-launch so terminal apps spawn correctly

* Use get_executable instead of get_commandline

* Add an option to set the hover colors

* Further improvements for the spawn function

* Fix scrolling/searching errors when there app list is empty

* This should never be nil anyway

* whitespace

* Refactor show, hide and toggle method + remove support for manually setting x an y (use placement)

* Add arguements for custom icon_theme (defaults to the selected system gtk theme) and icon_size (defaults to 48)

* Pass the app table instead of individual keys to create_app_widget

* Add an arguement to pass the default terminal for terminal apps as gtk-launch only uses xterm

* Reformating

* Rename 'mark_app' and 'unmark_app' to 'select_app' and 'unselect_app'

* Call :hide() from app.spawn() to avoid calling hide() twice on some cases

* Fix escape not closing the launcher after b7e44ec4

* Reduce code duplication and only reset the launcher when the animation is over (if not nil)

* Set active_widget to nil when the grid is empty to prevent from spawning the wrong app

* Override the default exe_callback

* Override the default behaviour for 'Return' via hooks instead because overriding only exe_callback still doesn't stop it from pausing the prompt keygrabber

* Set active_widget to nil on unselect

* Unselect previous app on search to avoid from spawning it when the grid is empty

* Use double quotes for everything
This commit is contained in:
Kasper 2021-11-05 05:38:54 +02:00 committed by GitHub
parent 0d8df18e02
commit e4fd438e3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 672 additions and 252 deletions

View File

@ -1,3 +1,12 @@
local tonumber = tonumber
local string = string
local math = math
local floor = math.floor
local max = math.max
local min = math.min
local abs = math.abs
local format = string.format
local _color = {} local _color = {}
--- Try to guess if a color is dark or light. --- Try to guess if a color is dark or light.
@ -13,6 +22,14 @@ function _color.is_dark(color)
return (numeric_value < 383) return (numeric_value < 383)
end end
function _color.is_opaque(color)
if type(color) == "string" then
color = _color.hex_to_rgba(color)
end
return color.a < 0.01
end
--- Lighten a color. --- Lighten a color.
-- --
-- @string color The color to lighten with hexadecimal HTML format `"#RRGGBB"`. -- @string color The color to lighten with hexadecimal HTML format `"#RRGGBB"`.
@ -49,4 +66,93 @@ function _color.darken(color, amount)
return _color.lighten(color, -amount) return _color.lighten(color, -amount)
end end
-- Returns a value that is clipped to interval edges if it falls outside the interval
function _color.clip(num, min_num, max_num)
return max(min(num, max_num), min_num)
end
-- Converts the given hex color to rgba
function _color.hex_to_rgba(color)
color = color:gsub("#", "")
return { r = tonumber("0x" .. color:sub(1, 2)),
g = tonumber("0x" .. color:sub(3, 4)),
b = tonumber("0x" .. color:sub(5, 6)),
a = #color == 8 and tonumber("0x" .. color:sub(7, 8)) or 255 }
end
-- Converts the given rgba color to hex
function _color.rgba_to_hex(color)
local r = _color.clip(color.r or color[1], 0, 255)
local g = _color.clip(color.g or color[2], 0, 255)
local b = _color.clip(color.b or color[3], 0, 255)
local a = _color.clip(color.a or color[4] or 255, 0, 255)
return "#" .. format("%02x%02x%02x%02x",
floor(r),
floor(g),
floor(b),
floor(a))
end
-- Converts the given hex color to hsv
function _color.hex_to_hsv(color)
local color = _color.hex2rgb(color)
local C_max = max(color.r, color.g, color.b)
local C_min = min(color.r, color.g, color.b)
local delta = C_max - C_min
local H, S, V
if delta == 0 then
H = 0
elseif C_max == color.r then
H = 60 * (((color.g - color.b) / delta) % 6)
elseif C_max == color.g then
H = 60 * (((color.b - color.r) / delta) + 2)
elseif C_max == color.b then
H = 60 * (((color.r - color.g) / delta) + 4)
end
if C_max == 0 then
S = 0
else
S = delta / C_max
end
V = C_max
return { h = H,
s = S * 100,
v = V * 100 }
end
-- Converts the given hsv color to hex
function _color.hsv_to_hex(H, S, V)
S = S / 100
V = V / 100
if H > 360 then H = 360 end
if H < 0 then H = 0 end
local C = V * S
local X = C * (1 - abs(((H / 60) % 2) - 1))
local m = V - C
local r_, g_, b_ = 0, 0, 0
if H >= 0 and H < 60 then
r_, g_, b_ = C, X, 0
elseif H >= 60 and H < 120 then
r_, g_, b_ = X, C, 0
elseif H >= 120 and H < 180 then
r_, g_, b_ = 0, C, X
elseif H >= 180 and H < 240 then
r_, g_, b_ = 0, X, C
elseif H >= 240 and H < 300 then
r_, g_, b_ = X, 0, C
elseif H >= 300 and H < 360 then
r_, g_, b_ = C, 0, X
end
local r, g, b = (r_ + m) * 255, (g_ + m) * 255, (b_ + m) * 255
return ("#%02x%02x%02x"):format(floor(r), floor(g), floor(b))
end
function _color.multiply(color, amount)
return { _color.clip(color.r * amount, 0, 255),
_color.clip(color.g * amount, 0, 255),
_color.clip(color.b * amount, 0, 255),
255 }
end
return _color return _color

View File

@ -55,6 +55,19 @@ function icon_theme:get_client_icon_path(client)
return icon return icon
end end
function icon_theme:choose_icon(icons_names)
local icon_info = Gtk.IconTheme.choose_icon(self.gtk_theme, icons_names, self.icon_size, 0);
if icon_info then
local icon_path = Gtk.IconInfo.get_filename(icon_info)
if icon_path then
return icon_path
end
end
return ""
end
function icon_theme:get_gicon_path(gicon) function icon_theme:get_gicon_path(gicon)
if gicon == nil then if gicon == nil then
return "" return ""

File diff suppressed because it is too large Load Diff