228 lines
8.0 KiB
C++
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);
|
|
};
|
|
}
|