114 lines
3.3 KiB
C++
114 lines
3.3 KiB
C++
/// Josh's User Interface Library
|
|
/// A C++20 Library for creating, styling, and rendering of a UI/UX widgets.
|
|
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
|
|
/// Special Thanks to William Tomasine II and Maxine Hayes.
|
|
/// (c) 2025 Redacted Software
|
|
/// This work is dedicated to the public domain.
|
|
|
|
/// @file Link.hpp
|
|
/// @desc Special category of text-objects that model a clickable link in HTML.
|
|
/// @edit 2025-06-11
|
|
|
|
#pragma once
|
|
#include <JUI/Widgets/Text.hpp>
|
|
|
|
#include "JUI/Mixins/Clickable.hpp"
|
|
|
|
|
|
namespace JUI {
|
|
|
|
struct LinkInvokedEventArgs {};
|
|
|
|
/// Controls when Link widgets fire their Cicked callback. It can fire right when the widget is clicked, or when it is is released.
|
|
enum class LinkClickMode { Press, Release };
|
|
|
|
/// The Link widget is a specialization of the Text widget that has the appearance and behavior of a clickable link, such as in HTML.
|
|
class Link : public Text, public Clickable, public Hoverable {
|
|
public:
|
|
enum LinkClickMode ClickMode = LinkClickMode::Release;
|
|
Event<std::optional<LinkInvokedEventArgs>> Invoked;
|
|
/// This event is fired when the user clicks/releases the link.
|
|
Link() : Text(), Clickable(), Hoverable() {}
|
|
explicit Link(const std::string& content) : Link() {
|
|
this->Content(content);
|
|
}
|
|
explicit Link(Widget* parent) : Link() {
|
|
this->Parent(parent);
|
|
}
|
|
|
|
|
|
void OnHover(const Vector2 &MousePos) override {
|
|
TextColor(Colors::Blues::CornflowerBlue);
|
|
}
|
|
|
|
void OnExit(const Vector2 &MousePos) override {
|
|
TextColor(Colors::Blues::DeepSkyBlue);
|
|
}
|
|
|
|
|
|
|
|
void OnClick(const Vector2& mouse_pos, const MouseButton& btn) override {
|
|
if (disabled)
|
|
return;
|
|
|
|
Clickable::OnClick(mouse_pos, btn);
|
|
|
|
TextColor(Colors::White);
|
|
|
|
if (!fire_on_release) {
|
|
Clicked.Invoke(std::nullopt);
|
|
already_clicked = true;
|
|
}
|
|
}
|
|
|
|
void OnRelease(const J3ML::LinearAlgebra::Vector2 &mouse_pos, const JUI::MouseButton &btn,
|
|
bool still_hovering) override {
|
|
|
|
if (disabled)
|
|
return;
|
|
|
|
Clickable::OnRelease(mouse_pos, btn, still_hovering);
|
|
|
|
TextColor(Colors::Black);
|
|
if (fire_on_release) {
|
|
Clicked.Invoke(std::nullopt);
|
|
already_clicked = true;
|
|
}
|
|
}
|
|
|
|
|
|
void Update(float delta) override {
|
|
|
|
Text::Update(delta);
|
|
|
|
// TODO: Why does hovered not handle this?
|
|
|
|
Hoverable::Update(IsMouseInside(), delta);
|
|
|
|
// TODO: This is duplicated between here and Window.cpp
|
|
// Will be abstracted away into Clickable shortly.
|
|
// OMFG
|
|
if (IsHovered() && mb_state && !prev_mb_state)
|
|
{
|
|
OnClick(last_known_mouse_pos, mbtn);
|
|
}
|
|
|
|
if (IsClicked() && !mb_state)
|
|
{
|
|
OnRelease(last_known_mouse_pos, mbtn, IsHovered());
|
|
}
|
|
}
|
|
protected:
|
|
Color4 already_clicked_color;
|
|
Color4 hovered_color;
|
|
Color4 clicked_color;
|
|
|
|
bool disabled = false;
|
|
|
|
bool already_clicked = false;
|
|
|
|
bool fire_on_release;
|
|
private:
|
|
};
|
|
}
|