Files
scummvm-cursorfix/engines/ags/shared/gui/gui_main.h
2026-02-02 04:50:13 +01:00

302 lines
12 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef AGS_SHARED_GUI_GUI_MAIN_H
#define AGS_SHARED_GUI_GUI_MAIN_H
#include "common/std/vector.h"
#include "ags/engine/ac/draw.h"
#include "ags/shared/ac/common.h"
#include "ags/shared/ac/common_defines.h" // TODO: split out gui drawing helpers
#include "ags/shared/gfx/gfx_def.h" // TODO: split out gui drawing helpers
#include "ags/shared/gui/gui_defines.h"
#include "ags/shared/util/error.h"
#include "ags/shared/util/geometry.h"
#include "ags/shared/util/string.h"
namespace AGS3 {
// Forward declaration
namespace AGS {
namespace Shared {
class Stream;
}
}
using namespace AGS; // FIXME later
class SplitLines;
#define LEGACY_MAX_OBJS_ON_GUI 30
#define GUIMAIN_LEGACY_RESERVED_INTS 5
#define GUIMAIN_LEGACY_NAME_LENGTH 16
#define GUIMAIN_LEGACY_EVENTHANDLER_LENGTH 20
#define GUIMAIN_LEGACY_TW_FLAGS_SIZE 4
namespace AGS {
namespace Shared {
// Legacy GUIMain visibility state, which combined Visible property and override factor
enum LegacyGUIVisState {
kGUIVisibility_LockedOff = -1, // locked hidden (used by PopupMouseY guis)
kGUIVisibility_Off = 0, // hidden
kGUIVisibility_On = 1 // shown
};
class Bitmap;
class GUIObject;
class GUIMain {
public:
static String FixupGUIName(const String &name);
public:
GUIMain();
void InitDefaults();
// Tells if the gui background supports alpha channel
bool HasAlphaChannel() const;
// Tells if GUI will react on clicking on it
bool IsClickable() const { return (_flags & kGUIMain_Clickable) != 0; }
// Tells if GUI's visibility is overridden and it won't be displayed on
// screen regardless of Visible property (until concealed mode is off).
bool IsConcealed() const { return (_flags & kGUIMain_Concealed) != 0; }
// Tells if gui is actually meant to be displayed on screen.
// Normally Visible property determines whether GUI is allowed to be seen,
// but there may be other settings that override it.
bool IsDisplayed() const { return IsVisible() && !IsConcealed(); }
// Tells if given coordinates are within interactable area of gui
// NOTE: this currently tests for actual visibility and Clickable property
bool IsInteractableAt(int x, int y) const;
// Tells if gui is a text window
bool IsTextWindow() const { return (_flags & kGUIMain_TextWindow) != 0; }
// Tells if GUI is *allowed* to be displayed and interacted with.
// This does not necessarily mean that it is displayed right now, because
// GUI may be hidden for other reasons, including overriding behavior.
// For example GUI with kGUIPopupMouseY style will not be shown unless
// mouse cursor is at certain position on screen.
bool IsVisible() const { return (_flags & kGUIMain_Visible) != 0; }
// Tells if GUI has graphically changed recently
bool HasChanged() const { return _hasChanged; }
bool HasControlsChanged() const { return _hasControlsChanged; }
// Manually marks GUI as graphically changed
// NOTE: this only matters if GUI's own graphic changes (content, size etc),
// but not its state (visible) or texture drawing mode (transparency, etc).
void MarkChanged();
// Marks GUI as having any of its controls changed its looks.
void MarkControlChanged();
// Clears changed flag
void ClearChanged();
// Notify GUI about any of its controls changing its location.
void NotifyControlPosition();
// Notify GUI about one of its controls changing its interactive state.
void NotifyControlState(int objid, bool mark_changed);
// Resets control-under-mouse detection.
void ResetOverControl();
// Finds a control under given screen coordinates, returns control's child ID.
// Optionally allows extra leeway (offset in all directions) to let the user grab tiny controls.
// Optionally only allows clickable controls, ignoring non-clickable ones.
int32_t FindControlAt(int atx, int aty, int leeway = 0, bool must_be_clickable = true) const;
// Gets the number of the GUI child controls
int32_t GetControlCount() const;
// Gets control by its child's index
GUIObject *GetControl(int32_t index) const;
// Gets child control's type, looks up with child's index
GUIControlType GetControlType(int32_t index) const;
// Gets child control's global ID, looks up with child's index
int32_t GetControlID(int32_t index) const;
// Gets an array of child control indexes in the z-order, from bottom to top
const std::vector<int> &GetControlsDrawOrder() const;
// Child control management
// Note that currently GUIMain does not own controls (should not delete them)
void AddControl(GUIControlType type, int32_t id, GUIObject *control);
void RemoveAllControls();
// Operations
bool BringControlToFront(int32_t index);
void DrawSelf(Bitmap *ds);
void DrawWithControls(Bitmap *ds);
// Polls GUI state, providing current cursor (mouse) coordinates
void Poll(int mx, int my);
HError RebuildArray();
void ResortZOrder();
bool SendControlToBack(int32_t index);
// Sets whether GUI should react to player clicking on it
void SetClickable(bool on);
// Override GUI visibility; when in concealed mode GUI won't show up
// even if Visible = true
void SetConceal(bool on);
// Attempts to change control's zorder; returns if zorder changed
bool SetControlZOrder(int32_t index, int zorder);
// Changes GUI style to the text window or back
void SetTextWindow(bool on);
// Sets GUI transparency as a percentage (0 - 100) where 100 = invisible
void SetTransparencyAsPercentage(int percent);
// Sets whether GUI is allowed to be displayed on screen
void SetVisible(bool on);
// Events
void OnMouseButtonDown(int mx, int my);
void OnMouseButtonUp();
// Serialization
void ReadFromFile(Stream *in, GuiVersion gui_version);
void WriteToFile(Stream *out) const;
// TODO: move to engine, into gui savegame component unit
// (should read/write GUI properties accessing them by interface)
void ReadFromSavegame(Stream *in, GuiSvgVersion svg_version);
void WriteToSavegame(Stream *out) const;
private:
void DrawBlob(Bitmap *ds, int x, int y, color_t draw_color);
// Same as FindControlAt but expects local space coordinates
int32_t FindControlAtLocal(int atx, int aty, int leeway, bool must_be_clickable) const;
// TODO: all members are currently public; hide them later
public:
int32_t ID; // GUI identifier
String Name; // the name of the GUI
int32_t X;
int32_t Y;
int32_t Width;
int32_t Height;
color_t BgColor; // background color
int32_t BgImage; // background sprite index
color_t FgColor; // foreground color (used as border color in normal GUIs,
// and text color in text windows)
int32_t Padding; // padding surrounding a GUI text window
GUIPopupStyle PopupStyle; // GUI popup behavior
int32_t PopupAtMouseY; // popup when _G(mousey) < this
int32_t Transparency; // "incorrect" alpha (in legacy 255-range units)
int32_t ZOrder;
int32_t FocusCtrl; // which control has the focus
int32_t HighlightCtrl; // which control has the bounding selection rect
int32_t MouseOverCtrl; // which control has the mouse cursor over it
int32_t MouseDownCtrl; // which control has the mouse button pressed on it
Point MouseWasAt; // last mouse cursor position
String OnClickHandler; // script function name
private:
int32_t _flags; // style and behavior flags
bool _hasChanged; // flag tells whether GUI has graphically changed recently
bool _hasControlsChanged;
bool _polling; // inside the polling process
// Array of types and control indexes in global GUI object arrays;
// maps GUI child slots to actual controls and used for rebuilding Controls array
typedef std::pair<GUIControlType, int32_t> ControlRef;
std::vector<ControlRef> _ctrlRefs;
// Array of child control references (not exclusively owned!)
std::vector<GUIObject *> _controls;
// Sorted array of controls in z-order.
std::vector<int> _ctrlDrawOrder;
};
namespace GUI {
extern GuiVersion GameGuiVersion;
extern GuiOptions Options;
// Applies current text direction setting (may depend on multiple factors)
String ApplyTextDirection(const String &text);
// Calculates the text's draw position, given the alignment
// optionally returns the real graphical rect that the text would occupy
Point CalcTextPosition(const char *text, int font, const Rect &frame, FrameAlignment align, Rect *gr_rect = nullptr);
// Calculates the text's draw position and horizontal extent,
// using strictly horizontal alignment
Line CalcTextPositionHor(const char *text, int font, int x1, int x2, int y, FrameAlignment align);
// Calculates the graphical rect that the text would occupy
// if drawn at the given coordinates
Rect CalcTextGraphicalRect(const char *text, int font, const Point &at);
// Calculates the graphical rect that the text would occupy
// if drawn aligned to the given frame
Rect CalcTextGraphicalRect(const char *text, int font, const Rect &frame, FrameAlignment align);
// Calculates a vertical graphical extent for a given font,
// which is a top and bottom offsets in zero-based coordinates.
// NOTE: this applies font size fixups.
Line CalcFontGraphicalVExtent(int font);
// Draw standart "shading" effect over rectangle
void DrawDisabledEffect(Bitmap *ds, const Rect &rc);
// Draw text aligned inside rectangle
void DrawTextAligned(Bitmap *ds, const char *text, int font, color_t text_color, const Rect &frame, FrameAlignment align);
// Draw text aligned horizontally inside given bounds
void DrawTextAlignedHor(Bitmap *ds, const char *text, int font, color_t text_color, int x1, int x2, int y, FrameAlignment align);
// Parses the string and returns combination of label macro flags
GUILabelMacro FindLabelMacros(const String &text);
// Applies text transformation necessary for rendering, in accordance to the
// current game settings, such as right-to-left render, and anything else
String TransformTextForDrawing(const String &text, bool translate, bool apply_direction);
// Wraps given text to make it fit into width, stores it in the lines;
// apply_direction param tells whether text direction setting should be applied
size_t SplitLinesForDrawing(const char *text, bool apply_direction, SplitLines &lines, int font, int width, size_t max_lines = -1);
// Mark all existing GUI for redraw
void MarkAllGUIForUpdate(bool redraw, bool reset_over_ctrl);
// Mark all translatable GUI controls for redraw
void MarkForTranslationUpdate();
// Mark all GUI which use the given font for recalculate/redraw;
// pass -1 to update all the textual controls together
void MarkForFontUpdate(int font);
// Mark labels that acts as special text placeholders for redraw
void MarkSpecialLabelsForUpdate(GUILabelMacro macro);
// Mark inventory windows for redraw, optionally only ones linked to given character;
// also marks buttons with inventory icon mode
void MarkInventoryForUpdate(int char_id, bool is_player);
// Reads all GUIs and their controls.
// WARNING: the data is read into the global arrays (guis, guibuts, and so on)
// TODO: remove is_savegame param after dropping support for old saves
// because only they use ReadGUI to read runtime GUI data
HError ReadGUI(Stream *in, bool is_savegame = false);
// Writes all GUIs and their controls.
// WARNING: the data is written from the global arrays (guis, guibuts, and so on)
void WriteGUI(Stream *out);
// Converts legacy GUIVisibility into appropriate GUIMain properties
void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis);
// Rebuilds GUIs, connecting them to the child controls in memory.
// WARNING: the data is processed in the global arrays (guis, guibuts, and so on)
HError RebuildGUI();
}
} // namespace Shared
} // namespace AGS
extern int get_adjusted_spritewidth(int spr);
extern int get_adjusted_spriteheight(int spr);
extern bool is_sprite_alpha(int spr);
extern void set_eip_guiobj(int eip);
extern int get_eip_guiobj();
} // namespace AGS3
#endif