1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-27 17:28:41 +00:00
luanti/src/ui/box.h
2025-06-01 18:41:24 -07:00

144 lines
3.4 KiB
C++

// Luanti
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (C) 2023 v-rob, Vincent Robinson <robinsonvincent89@gmail.com>
#pragma once
#include "ui/helpers.h"
#include "ui/style.h"
#include "util/basic_macros.h"
#include <array>
#include <iostream>
#include <string>
#include <vector>
union SDL_Event;
namespace ui
{
class Elem;
class Window;
class Box
{
public:
using State = u32;
// These states are organized in order of precedence. States with a
// larger value will override the styles of states with a lower value.
static constexpr State STATE_NONE = 0;
static constexpr State STATE_FOCUSED = 1 << 0;
static constexpr State STATE_SELECTED = 1 << 1;
static constexpr State STATE_HOVERED = 1 << 2;
static constexpr State STATE_PRESSED = 1 << 3;
static constexpr State STATE_DISABLED = 1 << 4;
static constexpr State NUM_STATES = 1 << 5;
// For groups that are standalone or not part of any particular group,
// this box group can be used.
static constexpr u32 NO_GROUP = -1;
// Represents a nonexistent box, i.e. a box with a group of NO_GROUP
// and an item of -1, which no box should use.
static constexpr u64 NO_ID = -1;
private:
// Indicates that there is no style string for this state combination.
static constexpr u32 NO_STYLE = -1;
// The element, group, and item are intrinsic to the box's identity, so
// they are set by the constructor and aren't cleared in reset() or
// changed in read().
Elem &m_elem;
u32 m_group;
u32 m_item;
std::vector<Box *> m_content;
std::string_view m_label;
Style m_style;
std::array<u32, NUM_STATES> m_style_refs;
// We cache the font and text content every time the box is restyled.
std::wstring m_text;
gui::IGUIFont *m_font;
// Cached information about the layout of the box, which is cleared in
// restyle() and recomputed in resize() and relayout().
SizeF m_min_layout;
SizeF m_min_content;
RectF m_display_rect;
RectF m_icon_rect;
RectF m_content_rect;
RectF m_clip_rect;
public:
Box(Elem &elem, u32 group, u32 item) :
m_elem(elem),
m_group(group),
m_item(item)
{
reset();
}
DISABLE_CLASS_COPY(Box)
Elem &getElem() { return m_elem; }
const Elem &getElem() const { return m_elem; }
Window &getWindow();
const Window &getWindow() const;
u32 getGroup() const { return m_group; }
u32 getItem() const { return m_item; }
u64 getId() const { return ((u64)m_group << 32) | (u64)m_item; }
const std::vector<Box *> &getContent() const { return m_content; }
void setContent(std::vector<Box *> content) { m_content = std::move(content); }
std::string_view getLabel() const { return m_label; }
void setLabel(std::string_view label) { m_label = label; }
void reset();
void read(std::istream &is);
void restyle();
void resize();
void relayout(RectF layout_rect, RectF layout_clip);
void draw();
bool isPointed() const;
bool isContentPointed() const;
bool processInput(const SDL_Event &event);
bool processFullPress(const SDL_Event &event, void (*on_press)(Elem &));
private:
static RectF getLayerSource(const Layer &layer);
static SizeF getLayerSize(const Layer &layer);
DispF getMiddleEdges();
void resizeBox();
void relayoutBox(RectF layout_rect, RectF layout_clip);
void resizePlace();
void relayoutPlace();
void drawBox();
void drawItems();
bool isHovered() const;
bool isPressed() const;
void setPressed(bool pressed);
void setHovered(bool hovered);
};
}