Skip to content

Commit

Permalink
feat: open file button, keypress/mouse wrapper, render on handled inp…
Browse files Browse the repository at this point in the history
…ut, rounded rect stroke
  • Loading branch information
f0e committed Nov 24, 2024
1 parent 053c42f commit ce4ac02
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 38 deletions.
86 changes: 58 additions & 28 deletions src/gui/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
#include "tasks.h"

#include "ui/ui.h"
#include "ui/keys.h"
#include "ui/utils.h"

#include "resources/fonts.h"

#define DEBUG_RENDER 0
#define DEBUG_RENDER 1

const int font_height = 14;
const int pad_x = 24;
Expand All @@ -25,7 +26,6 @@ const float default_delta_time = 1.f / 60;
float vsync_frame_time = default_delta_time;

bool closing = false;
bool actively_rendering = true;

SkFont font;
SkFont header_font;
Expand Down Expand Up @@ -80,12 +80,6 @@ static os::WindowRef create_window(os::DragTarget& dragTarget) {

bool processEvent(const os::Event& ev) {
switch (ev.type()) {
case os::Event::KeyDown: {
if (ev.scancode() == os::kKeyEsc)
return false;
break;
}

case os::Event::CloseApp:
case os::Event::CloseWindow: {
closing = true;
Expand All @@ -95,35 +89,62 @@ bool processEvent(const os::Event& ev) {
case os::Event::ResizeWindow:
break;

case os::Event::MouseMove: {
printf("mouse move bro! %d %d\n", ev.position().x, ev.position().y);
keys::on_mouse_move(
ev.position(),
ev.modifiers(),
ev.pointerType(),
ev.pressure()
);
return true;
}

case os::Event::MouseDown: {
base::paths paths;
utils::show_file_selector("Blur input", ".", { "mp4", "mkv" }, os::FileDialog::Type::OpenFiles, paths);
tasks::add_files(paths);
break;
keys::on_mouse_down(
ev.position(),
ev.button(),
ev.modifiers(),
ev.pointerType(),
ev.pressure()
);
return true;
}

case os::Event::MouseUp: {
keys::on_mouse_up(
ev.position(),
ev.button(),
ev.modifiers(),
ev.pointerType()
);
return true;
}

default:
break;
}

return true;
return false;
}

void gui::generate_messages_from_os_events() { // https://github.com/aseprite/aseprite/blob/45c2a5950445c884f5d732edc02989c3fb6ab1a6/src/ui/manager.cpp#L393
bool gui::generate_messages_from_os_events(bool rendered_last) { // https://github.com/aseprite/aseprite/blob/45c2a5950445c884f5d732edc02989c3fb6ab1a6/src/ui/manager.cpp#L393
os::Event event;

double timeout;
if (actively_rendering)
if (rendered_last)
timeout = 0.0;
else
timeout = 1.f / 60;

event_queue->getEvent(event, timeout);

processEvent(event);
return processEvent(event);
}

void gui::event_loop() {
bool to_render = true;

while (!closing) {
#ifdef _WIN32
HMONITOR screen_handle = (HMONITOR)window->screen()->nativeHandle();
Expand All @@ -145,10 +166,14 @@ void gui::event_loop() {

auto frame_start = std::chrono::steady_clock::now();

redraw_window(window.get(), false);
generate_messages_from_os_events();
bool rendered = redraw_window(window.get(), to_render);
to_render = generate_messages_from_os_events(rendered); // true if input handled

#if DEBUG_RENDER
printf("rendered: %d, to render: %d\n", rendered, to_render);
#endif

if (actively_rendering) {
if (rendered || to_render) {
auto target_time = frame_start + std::chrono::duration_cast<std::chrono::steady_clock::duration>(
std::chrono::duration<float>(vsync_frame_time)
);
Expand All @@ -157,7 +182,7 @@ void gui::event_loop() {
}
}

void gui::redraw_window(os::Window* window, bool force_render) {
bool gui::redraw_window(os::Window* window, bool force_render) {
auto now = std::chrono::steady_clock::now();
static auto last_frame_time = now;

Expand Down Expand Up @@ -193,14 +218,12 @@ void gui::redraw_window(os::Window* window, bool force_render) {
os::Surface* s = window->surface();
const gfx::Rect rc = s->bounds();

bool updated = false;

gfx::Rect drop_zone = rc;

static float bg_overlay_shade = 0.f;
float last_fill_shade = bg_overlay_shade;
bg_overlay_shade = std::lerp(bg_overlay_shade, windowData.dragging ? 30.f : 0.f, 25.f * delta_time);
updated |= bg_overlay_shade != last_fill_shade;
force_render |= bg_overlay_shade != last_fill_shade;

{
// const int blur_stroke_width = 1;
Expand Down Expand Up @@ -243,7 +266,12 @@ void gui::redraw_window(os::Window* window, bool force_render) {
title_pos.y = pad_y + header_font.getSize();

ui::add_text_fixed("blur title text", container, title_pos, "blur", gfx::rgba(255, 255, 255, 255), header_font, os::TextAlign::Center, 15);
ui::add_text("drop a file text", container, "Drop a file...", gfx::rgba(255, 255, 255, 255), font, os::TextAlign::Center);
ui::add_button("open a file button", container, "Open a file", font, [] {
base::paths paths;
utils::show_file_selector("Blur input", ".", { "mp4", "mkv" }, os::FileDialog::Type::OpenFiles, paths);
tasks::add_files(paths);
});
ui::add_text("drop a file text", container, "or drop a file anywhere", gfx::rgba(255, 255, 255, 255), font, os::TextAlign::Center);
}
else {
bool is_progress_shown = false;
Expand Down Expand Up @@ -291,11 +319,10 @@ void gui::redraw_window(os::Window* window, bool force_render) {

ui::center_elements_in_container(container);

bool last = actively_rendering;
actively_rendering = ui::update_container(s, container, delta_time) || updated || force_render;
if (!actively_rendering)
bool want_to_render = ui::update_container(s, container, delta_time) || force_render;
if (!want_to_render)
// note: DONT RENDER ANYTHING ABOVE HERE!!! todo: render queue?
return;
return false;

// background
os::Paint paint;
Expand Down Expand Up @@ -352,10 +379,13 @@ void gui::redraw_window(os::Window* window, bool force_render) {
}
#endif

// todo: whats this do
if (!window->isVisible())
window->setVisible(true);

window->invalidateRegion(gfx::Region(rc));

return true;
}

void gui::on_resize(os::Window* window) {
Expand Down
4 changes: 2 additions & 2 deletions src/gui/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ namespace gui {
inline os::WindowRef window;
inline bool queue_redraw = false;

void redraw_window(os::Window* window, bool force_render);
bool redraw_window(os::Window* window, bool force_render);
void on_resize(os::Window* window);

void generate_messages_from_os_events();
bool generate_messages_from_os_events(bool rendered_last);
void event_loop();

void run();
Expand Down
19 changes: 19 additions & 0 deletions src/gui/ui/keys.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "keys.h"

void keys::on_mouse_move(gfx::Point position, os::KeyModifiers modifiers, os::PointerType pointerType, float pressure) {
mouse_pos = position;
}

void keys::on_mouse_down(gfx::Point position, os::Event::MouseButton button, os::KeyModifiers modifiers, os::PointerType pointerType, float pressure) {
mouse_pos = position;
pressed_mouse_keys.insert(button);
}

void keys::on_mouse_up(gfx::Point position, os::Event::MouseButton button, os::KeyModifiers modifiers, os::PointerType pointerType) {
mouse_pos = position;
pressed_mouse_keys.erase(button);
}

bool keys::is_rect_pressed(gfx::Rect rect, os::Event::MouseButton button) {
return rect.contains(mouse_pos) && pressed_mouse_keys.contains(button);
}
12 changes: 12 additions & 0 deletions src/gui/ui/keys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

namespace keys {
inline gfx::Point mouse_pos;
inline std::unordered_set<os::Event::MouseButton> pressed_mouse_keys;

void on_mouse_move(gfx::Point position, os::KeyModifiers modifiers, os::PointerType pointerType, float pressure);
void on_mouse_down(gfx::Point position, os::Event::MouseButton button, os::KeyModifiers modifiers, os::PointerType pointerType, float pressure);
void on_mouse_up(gfx::Point position, os::Event::MouseButton button, os::KeyModifiers modifiers, os::PointerType pointerType);

bool is_rect_pressed(gfx::Rect rect, os::Event::MouseButton button);
}
33 changes: 28 additions & 5 deletions src/gui/ui/render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ void render::rect_filled(os::Surface* surface, gfx::Rect rect, gfx::Color colour
surface->drawRect(rect, paint);
}

void render::rounded_rect_filled(os::Surface* surface, gfx::Rect rect, gfx::Color colour, float rounding) {
void rounded_rect(os::Surface* surface, gfx::RectF rect, os::Paint paint, float rounding) {
if (rect.isEmpty())
return;

os::Paint paint;
paint.color(colour);

auto skia_rect = SkRect::MakeXYWH(SkScalar(rect.x), SkScalar(rect.y), SkScalar(rect.w), SkScalar(rect.h));
SkRect skia_rect;
if (paint.style() == os::Paint::Style::Stroke)
skia_rect = os::to_skia_fix(rect);
else
skia_rect = os::to_skia(rect);

SkRRect rrect;
rrect.setRectXY(skia_rect, rounding, rounding);
Expand All @@ -28,6 +29,28 @@ void render::rounded_rect_filled(os::Surface* surface, gfx::Rect rect, gfx::Colo
canvas->drawRRect(rrect, paint.skPaint());
}

void render::rounded_rect_filled(os::Surface* surface, gfx::Rect rect, gfx::Color colour, float rounding) {
if (rect.isEmpty())
return;

os::Paint paint;
paint.color(colour);

rounded_rect(surface, rect, paint, rounding);
}

void render::rounded_rect_stroke(os::Surface* surface, gfx::Rect rect, gfx::Color colour, float rounding, float stroke_width) {
if (rect.isEmpty())
return;

os::Paint paint;
paint.color(colour);
paint.style(os::Paint::Style::Stroke);
paint.strokeWidth(stroke_width);

rounded_rect(surface, rect, paint, rounding);
}

void render::text(os::Surface* surface, gfx::Point pos, gfx::Color colour, std::string text, const SkFont& font, os::TextAlign align) {
os::Paint paint;
paint.color(colour);
Expand Down
1 change: 1 addition & 0 deletions src/gui/ui/render.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace render {
void rect_filled(os::Surface* surface, gfx::Rect rect, gfx::Color colour);
void rounded_rect_filled(os::Surface* surface, gfx::Rect rect, gfx::Color colour, float rounding);
void rounded_rect_stroke(os::Surface* surface, gfx::Rect rect, gfx::Color colour, float rounding, float stroke_width = 1);
void text(os::Surface* surface, gfx::Point pos, gfx::Color colour, std::string text, const SkFont& font, os::TextAlign align = os::TextAlign::Left);

gfx::Size get_text_size(std::string text, const SkFont& font);
Expand Down
56 changes: 55 additions & 1 deletion src/gui/ui/ui.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include "ui.h"
#include "render.h"
#include "keys.h"
#include "os/draw_text.h"
#include "os/sampling.h"
#include "render.h"

gfx::Color adjust_color(const gfx::Color& color, float anim) {
return gfx::rgba(gfx::getr(color), gfx::getg(color), gfx::getb(color), round(gfx::geta(color) * anim)); // seta is broken or smth i swear
Expand Down Expand Up @@ -115,6 +116,42 @@ void ui::render_image(os::Surface* surface, const Element* element, float anim)
surface->drawRect(image_rect, stroke_paint);
}

void ui::render_button(os::Surface* surface, const Element* element, float anim) {
const float button_rounding = 10.f;

auto& button_data = std::get<ButtonElementData>(element->data);

bool hovered = element->rect.contains(keys::mouse_pos);

render::rect_filled(surface, gfx::Rect(keys::mouse_pos - 10, gfx::Size(10, 10)), gfx::rgba(0, 0, 255, 50));

if (button_data.on_press) {
if (keys::is_rect_pressed(element->rect, os::Event::MouseButton::LeftButton)) {
(*button_data.on_press)();
}
}

gfx::Color adjusted_color = adjust_color(gfx::rgba(255, 255, 255, hovered ? 100 : 20), anim);
gfx::Color adjusted_text_color = adjust_color(gfx::rgba(255, 255, 255, 255), anim);

gfx::Point text_pos = element->rect.center();
text_pos.y += button_data.font.getSize() / 2 - 1;
gfx::Rect cur_rect = element->rect;

// border
cur_rect.shrink(1);
render::rounded_rect_stroke(surface, cur_rect, adjust_color(gfx::rgba(100, 100, 100, 255), anim), button_rounding);
cur_rect.shrink(1);
render::rounded_rect_stroke(surface, cur_rect, adjust_color(gfx::rgba(50, 50, 50, 255), anim), button_rounding);
cur_rect.shrink(1);
render::rounded_rect_stroke(surface, cur_rect, adjust_color(gfx::rgba(100, 100, 100, 255), anim), button_rounding);

// fill
render::rounded_rect_filled(surface, cur_rect, adjusted_color, button_rounding);

render::text(surface, text_pos, adjusted_text_color, button_data.text, button_data.font, os::TextAlign::Center);
}

void ui::init_container(Container& container, gfx::Rect rect, const SkFont& font, std::optional<gfx::Color> background_color) {
container.line_height = font.getSize();
container.rect = rect;
Expand Down Expand Up @@ -260,6 +297,23 @@ std::optional<std::shared_ptr<ui::Element>> ui::add_image(const std::string& id,
return element;
}

std::shared_ptr<ui::Element> ui::add_button(const std::string& id, Container& container, const std::string& text, const SkFont& font, std::optional<std::function<void()>> on_press) {
const gfx::Size button_padding(40, 20);

gfx::Size text_size = render::get_text_size(text, font);

auto element = std::make_shared<Element>(Element{
ElementType::BUTTON,
gfx::Rect(container.current_position, text_size + button_padding),
ButtonElementData{ text, font, on_press },
render_button,
});

add_element(container, id, element, container.line_height);

return element;
}

void ui::center_elements_in_container(Container& container, bool horizontal, bool vertical) {
int total_height = container.current_position.y - container.rect.y;

Expand Down
Loading

0 comments on commit ce4ac02

Please sign in to comment.