Files
ReJUI/include/JUI/Widgets/Window.hpp

228 lines
8.0 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) 2024 Redacted Software
/// This work is dedicated to the public domain.
/// @file Window.hpp
/// @desc Window Widget - self-managed container for other widgets.
/// @edit 2024-08-01
#pragma once
#include <J3ML/LinearAlgebra.hpp>
#include <JUI/Base/Widget.hpp>
#include <JUI/Base/RectBase.hpp>
#include <JUI/Widgets/Rect.hpp>
#include <JUI/Widgets/Text.hpp>
#include <JUI/Widgets/Button.hpp>
#include <JUI/Mixins/Draggable.hpp>
#include <JUI/Mixins/Resizable.hpp>
#include <JUI/Mixins/Dockable.hpp>
#include <JUI/Mixins/Hoverable.hpp>
#include <JUI/Mixins/Clickable.hpp>
#include <JUI/Widgets/TextButton.hpp>
#include <JUI/Widgets/ImageButton.hpp>
namespace JUI {
using J3ML::LinearAlgebra::Vector2;
class DockingStation {};
/// A container widget class, with title bar and buttons,
/// which can be dragged around, resized, and docked into other applicable widgets.
class Window : public Widget, public RectBase, public Clickable, public Hoverable, public Draggable, public Resizable, public Dockable {
public:
Event<> OnOpen;
Event<> OnClose;
/// The default constructor sets a default style for this Window.
Window();
/// Construct a window widget by specifying it's parent.
explicit Window(Widget* parent);
/// Returns the current size (in x,y pixels) of the Window widget.
[[nodiscard]] Vector2 CurrentSize() const;
/// Returns the minimum size (in x,y pixels) that the Window widget is allowed to be.
[[nodiscard]] Vector2 MinSize() const;
/// Sets the minimum size (in x,y pixels) that the Window widget is allowed to be.
void MinSize(const Vector2& constraint);
/// Returns the maximum size (in x,y pixels) that the Window widget is allowed to be.
[[nodiscard]] Vector2 MaxSize() const;
/// Sets the maximum size (in x,y pixels) that the Window widget is allowed to be.
void MaxSize(const Vector2& constraint);
/// Returns the height (in pixels) of the Window's titlebar.
// TODO: Decide if this will auto-scale with the titlebar's text height, or the other way around.
[[nodiscard]] int TitlebarHeight() const;
void HideTitlebar() {
titlebar_hidden = true;
Topbar->Visible(false);
}
void ShowTitlebar() {
titlebar_hidden = false;
Topbar->Visible(true);
}
/// @return True if this window widget is on-top of all other window-widgets with the same parent.
bool OnTop() const;
/// Brings this window widget to the top of the window-widget stack.
void BringToTop();
/// Moves this window up in the window-widget stack.
void MoveUp() {
zindex++;
}
/// Moves this window down in the window-widget stack.
void MoveDown() {
zindex--;
}
void TitlebarHeight(int height);
/// Returns the text displayed as the Window's title.
[[nodiscard]] std::string Title() const;
void Title(const std::string& title);
/// Returns whether dragging the window about with the mouse is enabled.
/// @see class Draggable.
bool IsDraggable() const;
/// Sets the window to have the ability to be dragged around by the mouse.
void SetDraggable(bool value);
/// Returns whether this Window is able to be 'Docked' into another widget.
/// @see class Dockable.
bool IsDockable() const;
void SetDockable(bool value);
/// Align topbar buttons to the left.
void LayoutControlsLeft();
/// Align topbar buttons to the right.
void LayoutControlsRight();
/// Returns whether resizing the window via right-click is enabled.
/// @see class Resizable
bool IsResizable() const;
void SetResizable(bool value);
void CornerRounding(float radius) override;
/// Returns a pointer to the Text Widget that is used to render the title bar's text.
Text* TitleInstance();
/// Returns a pointer to the Rect Widget that is used to layout the title bar contents.
Rect* TopbarInstance();
/// Returns a pointer to the Rect Widget that is used to layout the contents of the window.
Rect* ViewportInstance();
Rect* Content();
/// Returns a pointer to the Exit Button Widget.
ImageButton* ExitButtonInstance();
Vector2 AbsoluteViewportPosition() const;
Vector2 AbsoluteViewportSize() const;
AABB2D AbsoluteViewportBounds() const;
/// Sets the font used by the title-bar text on this Window.
void SetTitleFont(const Font& f);
/// Toggles whether this window is actively being dragged by the mouse.
/// @see class Draggable.
void SetDrag(bool d) override;
/// @see class Widget.
void Update(float delta) override;
/// @see class Widget.
void Draw() override;
/// @see class Clickable.
void OnClick(const Vector2& m_pos, const MouseButton& m_btn) override;
/// @see class Clickable.
void OnRelease(const Vector2& m_pos, const MouseButton& m_btn, bool still_hovering) override;
/// @see class Hoverable. v
void OnHover(const J3ML::LinearAlgebra::Vector2 &MousePos) override
{
Hoverable::OnHover(MousePos);
zindex++;
focused = true;
this->BorderColor(Style::Window::OutlineColor);
this->BGColor(Style::Window::OutlineColor);
}
/// @see class Hoverable.
void OnExit(const J3ML::LinearAlgebra::Vector2 &MousePos) override {
Hoverable::OnExit(MousePos);
zindex--;
focused = false;
this->BorderColor(Style::Window::UnfocusedOutlineColor);
this->BGColor(Style::Window::UnfocusedOutlineColor);
}
/// @return whether this window will consume this observed mouse movement.
/// @note This is to prevent a user-mouse-action from being picked up by multiple widgets.
bool ObserveMouseMovement(const Vector2 &latest_known_pos) override;
bool ObserveMouseInput(JUI::MouseButton btn, bool pressed) override
{
// TODO: Consider how this plays with Clickable::OnClick and Clickable::OnRelease
if (visible) {
if (!pressed)
return Widget::ObserveMouseInput(btn, false);
if (this->focused)
return Widget::ObserveMouseInput(btn, pressed);
}
// Special case to allow drop of "Resizing"
if (btn == MouseButton::Right && pressed == false)
return Widget::ObserveMouseInput(btn, pressed);
return false;
}
[[nodiscard]] bool IsOpen() const;
[[nodiscard]] bool IsClosed() const;
virtual void Open();
virtual void Close();
virtual void SetOpen(bool value);
virtual void Toggle();
protected:
void UpdateInternalWidgetsTitlebarHeight();
protected:
JUI::Rect* Topbar = nullptr;
JUI::Rect* Viewport = nullptr;
JUI::Text* TitleLabel = nullptr;
JUI::ImageButton* exit_btn = nullptr;
JUI::ImageButton* fs_btn = nullptr;
std::string title = "JUI Window";
bool resizable = true;
bool focused = false;
bool open = false;
//bool resizing = false;
bool draggable = true;
bool titlebar_hidden = false;
bool dockable = false;
int titlebar_height = Style::Window::TitlebarHeight;
int title_font_size = 16;
Vector2 max_size = {800, 600};
Vector2 min_size = {200, 100}; //= {30, 30};
UDim2 size_when_restart_began;
void DragTo(const Vector2 &pos);
};
}