Make windows control buttons active
This commit is contained in:
parent
8ad87d77da
commit
67dc16ad26
|
@ -1,44 +1,109 @@
|
||||||
local core = require "core"
|
local core = require "core"
|
||||||
|
local common = require "core.common"
|
||||||
local style = require "core.style"
|
local style = require "core.style"
|
||||||
local StatusView = require "core.statusview"
|
local View = require "core.view"
|
||||||
|
|
||||||
|
local title_commands = {
|
||||||
|
{symbol = "_", action = function() system.set_window_mode("minimized") end},
|
||||||
|
{symbol = "w", action = function() system.set_window_mode("maximized") end},
|
||||||
|
{symbol = "W", action = function() core.quit() end},
|
||||||
|
}
|
||||||
|
|
||||||
local TitleView = StatusView:extend()
|
local TitleView = View:extend()
|
||||||
|
|
||||||
TitleView.separator = " "
|
local function title_view_height()
|
||||||
|
return style.font:get_height() + style.padding.y * 2
|
||||||
|
end
|
||||||
|
|
||||||
function TitleView:new()
|
function TitleView:new()
|
||||||
TitleView.super.new(self)
|
TitleView.super.new(self)
|
||||||
|
-- FIXME: decide if visible is actually needed
|
||||||
|
self.visible = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function TitleView:on_mouse_pressed()
|
|
||||||
core.set_active_view(core.last_active_view)
|
|
||||||
end
|
|
||||||
|
|
||||||
function TitleView:on_mouse_moved(px, py, ...)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function TitleView:update()
|
function TitleView:update()
|
||||||
|
if self.visible then
|
||||||
|
self.size.y = title_view_height()
|
||||||
|
else
|
||||||
|
self.size.y = 0
|
||||||
|
end
|
||||||
TitleView.super.update(self)
|
TitleView.super.update(self)
|
||||||
local title_height = self.size.y
|
local title_height = self.size.y
|
||||||
if core.window_borderless and title_height ~= core.hit_test_title_height then
|
if core.window_borderless and title_height ~= core.hit_test_title_height then
|
||||||
local resize_border = title_height / 2
|
local icon_w = style.icon_font:get_width("_")
|
||||||
system.set_window_hit_test(title_height, resize_border)
|
local icon_spacing = icon_w
|
||||||
|
local controls_width = (icon_w + icon_spacing) * #title_commands + icon_spacing
|
||||||
|
system.set_window_hit_test(title_height, controls_width, icon_spacing)
|
||||||
core.hit_test_title_height = title_height
|
core.hit_test_title_height = title_height
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function TitleView:get_items()
|
function TitleView:draw_window_title()
|
||||||
|
local h = style.font:get_height()
|
||||||
|
local ox, oy = self:get_content_offset()
|
||||||
|
local color = style.text
|
||||||
|
local x, y = ox + style.padding.x, oy + style.padding.y
|
||||||
|
x = common.draw_text(style.icon_font, color, "M ", nil, x, y, 0, h)
|
||||||
local title = core.compose_window_title(core.window_title)
|
local title = core.compose_window_title(core.window_title)
|
||||||
return {
|
common.draw_text(style.font, color, title, nil, x, y, 0, h)
|
||||||
style.text, style.icon_font, "M ", style.font, title,
|
end
|
||||||
}, {
|
|
||||||
style.text, style.icon_font, "_", TitleView.separator, "w", TitleView.separator, "W",
|
function TitleView:each_control_item()
|
||||||
}
|
local icon_h, icon_w = style.icon_font:get_height(), style.icon_font:get_width("_")
|
||||||
|
local icon_spacing = icon_w
|
||||||
|
local ox, oy = self:get_content_offset()
|
||||||
|
ox = ox + self.size.x
|
||||||
|
local i, n = 0, #title_commands
|
||||||
|
local iter = function()
|
||||||
|
i = i + 1
|
||||||
|
if i <= n then
|
||||||
|
local dx = - (icon_w + icon_spacing) * (n - i + 1)
|
||||||
|
local dy = style.padding.y
|
||||||
|
return title_commands[i], ox + dx, oy + dy, icon_w, icon_h
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return iter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TitleView:draw_window_controls()
|
||||||
|
for item, x, y, w, h in self:each_control_item() do
|
||||||
|
local color = item == self.hovered_item and style.text or style.dim
|
||||||
|
common.draw_text(style.icon_font, color, item.symbol, nil, x, y, 0, h)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TitleView:on_mouse_pressed(button, x, y, clicks)
|
||||||
|
local caught = TitleView.super.on_mouse_pressed(self, button, x, y, clicks)
|
||||||
|
if caught then return end
|
||||||
|
core.set_active_view(core.last_active_view)
|
||||||
|
if self.hovered_item then
|
||||||
|
self.hovered_item.action()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TitleView:on_mouse_moved(px, py, ...)
|
||||||
|
TitleView.super.on_mouse_moved(self, px, py, ...)
|
||||||
|
self.hovered_item = nil
|
||||||
|
local x_min, x_max, y_min, y_max = self.size.x, 0, self.size.y, 0
|
||||||
|
for item, x, y, w, h in self:each_control_item() do
|
||||||
|
x_min, x_max = math.min(x, x_min), math.max(x + w, x_max)
|
||||||
|
y_min, y_max = y, y + h
|
||||||
|
if px > x and py > y and px <= x + w and py <= y + h then
|
||||||
|
self.hovered_item = item
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TitleView:draw()
|
||||||
|
self:draw_background(style.background2)
|
||||||
|
self:draw_window_title()
|
||||||
|
self:draw_window_controls()
|
||||||
|
end
|
||||||
|
|
||||||
return TitleView
|
return TitleView
|
||||||
|
|
|
@ -37,6 +37,7 @@ static char* key_name(char *dst, int sym) {
|
||||||
|
|
||||||
struct HitTestInfo {
|
struct HitTestInfo {
|
||||||
int title_height;
|
int title_height;
|
||||||
|
int controls_width;
|
||||||
int resize_border;
|
int resize_border;
|
||||||
};
|
};
|
||||||
typedef struct HitTestInfo HitTestInfo;
|
typedef struct HitTestInfo HitTestInfo;
|
||||||
|
@ -46,11 +47,13 @@ static HitTestInfo window_hit_info[1] = {{0, 0}};
|
||||||
static SDL_HitTestResult SDLCALL hit_test(SDL_Window *window, const SDL_Point *pt, void *data) {
|
static SDL_HitTestResult SDLCALL hit_test(SDL_Window *window, const SDL_Point *pt, void *data) {
|
||||||
const HitTestInfo *hit_info = (HitTestInfo *) data;
|
const HitTestInfo *hit_info = (HitTestInfo *) data;
|
||||||
const int resize_border = hit_info->resize_border;
|
const int resize_border = hit_info->resize_border;
|
||||||
|
const int controls_width = hit_info->controls_width;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
SDL_GetWindowSize(window, &w, &h);
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
|
|
||||||
if (pt->y < hit_info->title_height && pt->x > resize_border && pt->x < w - resize_border) {
|
if (pt->y < hit_info->title_height && pt->y > hit_info->resize_border &&
|
||||||
|
pt->x > resize_border && pt->x < w - controls_width) {
|
||||||
return SDL_HITTEST_DRAGGABLE;
|
return SDL_HITTEST_DRAGGABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +63,7 @@ static SDL_HitTestResult SDLCALL hit_test(SDL_Window *window, const SDL_Point *p
|
||||||
|
|
||||||
if (pt->x < resize_border && pt->y < resize_border) {
|
if (pt->x < resize_border && pt->y < resize_border) {
|
||||||
REPORT_RESIZE_HIT(TOPLEFT);
|
REPORT_RESIZE_HIT(TOPLEFT);
|
||||||
} else if (pt->x > resize_border && pt->x < w - resize_border && pt->y < resize_border) {
|
} else if (pt->x > resize_border && pt->x < w - controls_width && pt->y < resize_border) {
|
||||||
REPORT_RESIZE_HIT(TOP);
|
REPORT_RESIZE_HIT(TOP);
|
||||||
} else if (pt->x > w - resize_border && pt->y < resize_border) {
|
} else if (pt->x > w - resize_border && pt->y < resize_border) {
|
||||||
REPORT_RESIZE_HIT(TOPRIGHT);
|
REPORT_RESIZE_HIT(TOPRIGHT);
|
||||||
|
@ -231,8 +234,8 @@ static int f_set_window_title(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *window_opts[] = { "normal", "maximized", "fullscreen", 0 };
|
static const char *window_opts[] = { "normal", "minimized", "maximized", "fullscreen", 0 };
|
||||||
enum { WIN_NORMAL, WIN_MAXIMIZED, WIN_FULLSCREEN };
|
enum { WIN_NORMAL, WIN_MINIMIZED, WIN_MAXIMIZED, WIN_FULLSCREEN };
|
||||||
|
|
||||||
static int f_set_window_mode(lua_State *L) {
|
static int f_set_window_mode(lua_State *L) {
|
||||||
int n = luaL_checkoption(L, 1, "normal", window_opts);
|
int n = luaL_checkoption(L, 1, "normal", window_opts);
|
||||||
|
@ -240,6 +243,7 @@ static int f_set_window_mode(lua_State *L) {
|
||||||
n == WIN_FULLSCREEN ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
n == WIN_FULLSCREEN ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||||
if (n == WIN_NORMAL) { SDL_RestoreWindow(window); }
|
if (n == WIN_NORMAL) { SDL_RestoreWindow(window); }
|
||||||
if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window); }
|
if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window); }
|
||||||
|
if (n == WIN_MINIMIZED) { SDL_MinimizeWindow(window); }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +257,8 @@ static int f_set_window_bordered(lua_State *L) {
|
||||||
|
|
||||||
static int f_set_window_hit_test(lua_State *L) {
|
static int f_set_window_hit_test(lua_State *L) {
|
||||||
window_hit_info->title_height = luaL_checknumber(L, 1);
|
window_hit_info->title_height = luaL_checknumber(L, 1);
|
||||||
window_hit_info->resize_border = luaL_checknumber(L, 2);
|
window_hit_info->controls_width = luaL_checknumber(L, 2);
|
||||||
|
window_hit_info->resize_border = luaL_checknumber(L, 3);
|
||||||
if (SDL_SetWindowHitTest(window, hit_test, window_hit_info) == -1) {
|
if (SDL_SetWindowHitTest(window, hit_test, window_hit_info) == -1) {
|
||||||
lua_pushboolean(L, 0);
|
lua_pushboolean(L, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue