Add zwidget
This commit is contained in:
parent
e7285cd6d9
commit
113fdc5fcc
54 changed files with 9321 additions and 0 deletions
63
libraries/ZWidget/include/zwidget/core/canvas.h
Normal file
63
libraries/ZWidget/include/zwidget/core/canvas.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class Font;
|
||||
class Image;
|
||||
class Point;
|
||||
class Rect;
|
||||
class Colorf;
|
||||
class DisplayWindow;
|
||||
struct VerticalTextPosition;
|
||||
|
||||
class FontMetrics
|
||||
{
|
||||
public:
|
||||
double ascent = 0.0;
|
||||
double descent = 0.0;
|
||||
double external_leading = 0.0;
|
||||
double height = 0.0;
|
||||
};
|
||||
|
||||
class Canvas
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<Canvas> create(DisplayWindow* window);
|
||||
|
||||
virtual ~Canvas() = default;
|
||||
|
||||
virtual void begin(const Colorf& color) = 0;
|
||||
virtual void end() = 0;
|
||||
|
||||
virtual void begin3d() = 0;
|
||||
virtual void end3d() = 0;
|
||||
|
||||
virtual Point getOrigin() = 0;
|
||||
virtual void setOrigin(const Point& origin) = 0;
|
||||
|
||||
virtual void pushClip(const Rect& box) = 0;
|
||||
virtual void popClip() = 0;
|
||||
|
||||
virtual void fillRect(const Rect& box, const Colorf& color) = 0;
|
||||
virtual void line(const Point& p0, const Point& p1, const Colorf& color) = 0;
|
||||
|
||||
virtual void drawText(const Point& pos, const Colorf& color, const std::string& text) = 0;
|
||||
virtual Rect measureText(const std::string& text) = 0;
|
||||
virtual VerticalTextPosition verticalTextAlign() = 0;
|
||||
|
||||
virtual void drawText(const std::shared_ptr<Font>& font, const Point& pos, const std::string& text, const Colorf& color) = 0;
|
||||
virtual void drawTextEllipsis(const std::shared_ptr<Font>& font, const Point& pos, const Rect& clipBox, const std::string& text, const Colorf& color) = 0;
|
||||
virtual Rect measureText(const std::shared_ptr<Font>& font, const std::string& text) = 0;
|
||||
virtual FontMetrics getFontMetrics(const std::shared_ptr<Font>& font) = 0;
|
||||
virtual int getCharacterIndex(const std::shared_ptr<Font>& font, const std::string& text, const Point& hitPoint) = 0;
|
||||
|
||||
virtual void drawImage(const std::shared_ptr<Image>& image, const Point& pos) = 0;
|
||||
};
|
||||
|
||||
struct VerticalTextPosition
|
||||
{
|
||||
double top = 0.0;
|
||||
double baseline = 0.0;
|
||||
double bottom = 0.0;
|
||||
};
|
||||
36
libraries/ZWidget/include/zwidget/core/colorf.h
Normal file
36
libraries/ZWidget/include/zwidget/core/colorf.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
|
||||
class Colorf
|
||||
{
|
||||
public:
|
||||
Colorf() = default;
|
||||
Colorf(float r, float g, float b, float a = 1.0f) : r(r), g(g), b(b), a(a) { }
|
||||
|
||||
static Colorf transparent() { return { 0.0f, 0.0f, 0.0f, 0.0f }; }
|
||||
|
||||
static Colorf fromRgba8(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255)
|
||||
{
|
||||
float s = 1.0f / 255.0f;
|
||||
return { r * s, g * s, b * s, a * s };
|
||||
}
|
||||
|
||||
uint32_t toBgra8() const
|
||||
{
|
||||
uint32_t cr = (int)(std::max(std::min(r * 255.0f, 255.0f), 0.0f));
|
||||
uint32_t cg = (int)(std::max(std::min(g * 255.0f, 255.0f), 0.0f));
|
||||
uint32_t cb = (int)(std::max(std::min(b * 255.0f, 255.0f), 0.0f));
|
||||
uint32_t ca = (int)(std::max(std::min(a * 255.0f, 255.0f), 0.0f));
|
||||
return (ca << 24) | (cr << 16) | (cg << 8) | cb;
|
||||
}
|
||||
|
||||
bool operator==(const Colorf& v) const { return r == v.r && g == v.g && b == v.b && a == v.a; }
|
||||
bool operator!=(const Colorf& v) const { return r != v.r || g != v.g || b != v.b || a != v.a; }
|
||||
|
||||
float r = 0.0f;
|
||||
float g = 0.0f;
|
||||
float b = 0.0f;
|
||||
float a = 1.0f;
|
||||
};
|
||||
15
libraries/ZWidget/include/zwidget/core/font.h
Normal file
15
libraries/ZWidget/include/zwidget/core/font.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
virtual ~Font() = default;
|
||||
|
||||
virtual const std::string& GetName() const = 0;
|
||||
virtual double GetHeight() const = 0;
|
||||
|
||||
static std::shared_ptr<Font> Create(const std::string& name, double height);
|
||||
};
|
||||
22
libraries/ZWidget/include/zwidget/core/image.h
Normal file
22
libraries/ZWidget/include/zwidget/core/image.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
enum class ImageFormat
|
||||
{
|
||||
R8G8B8A8,
|
||||
B8G8R8A8
|
||||
};
|
||||
|
||||
class Image
|
||||
{
|
||||
public:
|
||||
virtual ~Image() = default;
|
||||
|
||||
virtual int GetWidth() const = 0;
|
||||
virtual int GetHeight() const = 0;
|
||||
virtual ImageFormat GetFormat() const = 0;
|
||||
virtual void* GetData() const = 0;
|
||||
|
||||
static std::shared_ptr<Image> Create(int width, int height, ImageFormat format, const void* data);
|
||||
};
|
||||
74
libraries/ZWidget/include/zwidget/core/rect.h
Normal file
74
libraries/ZWidget/include/zwidget/core/rect.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
Point() = default;
|
||||
Point(double x, double y) : x(x), y(y) { }
|
||||
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
|
||||
Point& operator+=(const Point& p) { x += p.x; y += p.y; return *this; }
|
||||
Point& operator-=(const Point& p) { x -= p.x; y -= p.y; return *this; }
|
||||
};
|
||||
|
||||
class Size
|
||||
{
|
||||
public:
|
||||
Size() = default;
|
||||
Size(double width, double height) : width(width), height(height) { }
|
||||
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
};
|
||||
|
||||
class Rect
|
||||
{
|
||||
public:
|
||||
Rect() = default;
|
||||
Rect(const Point& p, const Size& s) : x(p.x), y(p.y), width(s.width), height(s.height) { }
|
||||
Rect(double x, double y, double width, double height) : x(x), y(y), width(width), height(height) { }
|
||||
|
||||
Point pos() const { return { x, y }; }
|
||||
Size size() const { return { width, height }; }
|
||||
|
||||
Point topLeft() const { return { x, y }; }
|
||||
Point topRight() const { return { x + width, y }; }
|
||||
Point bottomLeft() const { return { x, y + height }; }
|
||||
Point bottomRight() const { return { x + width, y + height }; }
|
||||
|
||||
double left() const { return x; }
|
||||
double top() const { return y; }
|
||||
double right() const { return x + width; }
|
||||
double bottom() const { return y + height; }
|
||||
|
||||
static Rect xywh(double x, double y, double width, double height) { return Rect(x, y, width, height); }
|
||||
static Rect ltrb(double left, double top, double right, double bottom) { return Rect(left, top, right - left, bottom - top); }
|
||||
|
||||
bool contains(const Point& p) const { return (p.x >= x && p.x < x + width) && (p.y >= y && p.y < y + height); }
|
||||
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
};
|
||||
|
||||
inline Point operator+(const Point& a, const Point& b) { return Point(a.x + b.x, a.y + b.y); }
|
||||
inline Point operator-(const Point& a, const Point& b) { return Point(a.x - b.x, a.y - b.y); }
|
||||
inline bool operator==(const Point& a, const Point& b) { return a.x == b.x && a.y == b.y; }
|
||||
inline bool operator!=(const Point& a, const Point& b) { return a.x != b.x || a.y != b.y; }
|
||||
inline bool operator==(const Size& a, const Size& b) { return a.width == b.width && a.height == b.height; }
|
||||
inline bool operator!=(const Size& a, const Size& b) { return a.width != b.width || a.height != b.height; }
|
||||
inline bool operator==(const Rect& a, const Rect& b) { return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; }
|
||||
inline bool operator!=(const Rect& a, const Rect& b) { return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height; }
|
||||
|
||||
inline Point operator+(const Point& a, double b) { return Point(a.x + b, a.y + b); }
|
||||
inline Point operator-(const Point& a, double b) { return Point(a.x - b, a.y - b); }
|
||||
inline Point operator*(const Point& a, double b) { return Point(a.x * b, a.y * b); }
|
||||
inline Point operator/(const Point& a, double b) { return Point(a.x / b, a.y / b); }
|
||||
|
||||
inline Size operator+(const Size& a, double b) { return Size(a.width + b, a.height + b); }
|
||||
inline Size operator-(const Size& a, double b) { return Size(a.width - b, a.height - b); }
|
||||
inline Size operator*(const Size& a, double b) { return Size(a.width * b, a.height * b); }
|
||||
inline Size operator/(const Size& a, double b) { return Size(a.width / b, a.height / b); }
|
||||
7
libraries/ZWidget/include/zwidget/core/resourcedata.h
Normal file
7
libraries/ZWidget/include/zwidget/core/resourcedata.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
std::vector<uint8_t> LoadWidgetFontData(const std::string& name);
|
||||
238
libraries/ZWidget/include/zwidget/core/span_layout.h
Normal file
238
libraries/ZWidget/include/zwidget/core/span_layout.h
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "colorf.h"
|
||||
#include "rect.h"
|
||||
#include "font.h"
|
||||
#include "canvas.h"
|
||||
|
||||
class Widget;
|
||||
class Image;
|
||||
class Canvas;
|
||||
|
||||
enum SpanAlign
|
||||
{
|
||||
span_left,
|
||||
span_right,
|
||||
span_center,
|
||||
span_justify
|
||||
};
|
||||
|
||||
class SpanLayout
|
||||
{
|
||||
public:
|
||||
SpanLayout();
|
||||
~SpanLayout();
|
||||
|
||||
struct HitTestResult
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
no_objects_available,
|
||||
outside_top,
|
||||
outside_left,
|
||||
outside_right,
|
||||
outside_bottom,
|
||||
inside
|
||||
};
|
||||
|
||||
Type type = {};
|
||||
int object_id = -1;
|
||||
size_t offset = 0;
|
||||
};
|
||||
|
||||
void Clear();
|
||||
|
||||
void AddText(const std::string& text, std::shared_ptr<Font> font, const Colorf& color = Colorf(), int id = -1);
|
||||
void AddImage(const std::shared_ptr<Image> image, double baseline_offset = 0, int id = -1);
|
||||
void AddWidget(Widget* component, double baseline_offset = 0, int id = -1);
|
||||
|
||||
void Layout(Canvas* canvas, double max_width);
|
||||
|
||||
void SetPosition(const Point& pos);
|
||||
|
||||
Size GetSize() const;
|
||||
Rect GetRect() const;
|
||||
|
||||
std::vector<Rect> GetRectById(int id) const;
|
||||
|
||||
HitTestResult HitTest(Canvas* canvas, const Point& pos);
|
||||
|
||||
void DrawLayout(Canvas* canvas);
|
||||
|
||||
/// Draw layout generating ellipsis for clipped text
|
||||
void DrawLayoutEllipsis(Canvas* canvas, const Rect& content_rect);
|
||||
|
||||
void SetComponentGeometry();
|
||||
|
||||
Size FindPreferredSize(Canvas* canvas);
|
||||
|
||||
void SetSelectionRange(std::string::size_type start, std::string::size_type end);
|
||||
void SetSelectionColors(const Colorf& foreground, const Colorf& background);
|
||||
|
||||
void ShowCursor();
|
||||
void HideCursor();
|
||||
|
||||
void SetCursorPos(std::string::size_type pos);
|
||||
void SetCursorOverwriteMode(bool enable);
|
||||
void SetCursorColor(const Colorf& color);
|
||||
|
||||
std::string GetCombinedText() const;
|
||||
|
||||
void SetAlign(SpanAlign align);
|
||||
|
||||
double GetFirstBaselineOffset();
|
||||
double GetLastBaselineOffset();
|
||||
|
||||
private:
|
||||
struct TextBlock
|
||||
{
|
||||
size_t start = 0;
|
||||
size_t end = 0;
|
||||
};
|
||||
|
||||
enum ObjectType
|
||||
{
|
||||
object_text,
|
||||
object_image,
|
||||
object_component
|
||||
};
|
||||
|
||||
enum FloatType
|
||||
{
|
||||
float_none,
|
||||
float_left,
|
||||
float_right
|
||||
};
|
||||
|
||||
struct SpanObject
|
||||
{
|
||||
ObjectType type = object_text;
|
||||
FloatType float_type = float_none;
|
||||
|
||||
std::shared_ptr<Font> font;
|
||||
Colorf color;
|
||||
size_t start = 0, end = 0;
|
||||
|
||||
std::shared_ptr<Image> image;
|
||||
Widget* component = nullptr;
|
||||
double baseline_offset = 0;
|
||||
|
||||
int id = -1;
|
||||
};
|
||||
|
||||
struct LineSegment
|
||||
{
|
||||
ObjectType type = object_text;
|
||||
|
||||
std::shared_ptr<Font> font;
|
||||
Colorf color;
|
||||
size_t start = 0;
|
||||
size_t end = 0;
|
||||
double ascender = 0;
|
||||
double descender = 0;
|
||||
|
||||
double x_position = 0;
|
||||
double width = 0;
|
||||
|
||||
std::shared_ptr<Image> image;
|
||||
Widget* component = nullptr;
|
||||
double baseline_offset = 0;
|
||||
|
||||
int id = -1;
|
||||
};
|
||||
|
||||
struct Line
|
||||
{
|
||||
double width = 0; // Width of the entire line (including spaces)
|
||||
double height = 0;
|
||||
double ascender = 0;
|
||||
std::vector<LineSegment> segments;
|
||||
};
|
||||
|
||||
struct TextSizeResult
|
||||
{
|
||||
size_t start = 0;
|
||||
size_t end = 0;
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
double ascender = 0;
|
||||
double descender = 0;
|
||||
int objects_traversed = 0;
|
||||
std::vector<LineSegment> segments;
|
||||
};
|
||||
|
||||
struct CurrentLine
|
||||
{
|
||||
std::vector<SpanObject>::size_type object_index = 0;
|
||||
Line cur_line;
|
||||
double x_position = 0;
|
||||
double y_position = 0;
|
||||
};
|
||||
|
||||
struct FloatBox
|
||||
{
|
||||
Rect rect;
|
||||
ObjectType type = object_image;
|
||||
std::shared_ptr<Image> image;
|
||||
Widget* component = nullptr;
|
||||
int id = -1;
|
||||
};
|
||||
|
||||
TextSizeResult FindTextSize(Canvas* canvas, const TextBlock& block, size_t object_index);
|
||||
std::vector<TextBlock> FindTextBlocks();
|
||||
void LayoutLines(Canvas* canvas, double max_width);
|
||||
void LayoutText(Canvas* canvas, std::vector<TextBlock> blocks, std::vector<TextBlock>::size_type block_index, CurrentLine& current_line, double max_width);
|
||||
void LayoutBlock(CurrentLine& current_line, double max_width, std::vector<TextBlock>& blocks, std::vector<TextBlock>::size_type block_index);
|
||||
void LayoutFloatBlock(CurrentLine& current_line, double max_width);
|
||||
void LayoutInlineBlock(CurrentLine& current_line, double max_width, std::vector<TextBlock>& blocks, std::vector<TextBlock>::size_type block_index);
|
||||
void ReflowLine(CurrentLine& current_line, double max_width);
|
||||
FloatBox FloatBoxLeft(FloatBox float_box, double max_width);
|
||||
FloatBox FloatBoxRight(FloatBox float_box, double max_width);
|
||||
FloatBox FloatBoxAny(FloatBox box, double max_width, const std::vector<FloatBox>& floats1);
|
||||
bool BoxFitsOnLine(const FloatBox& box, double max_width);
|
||||
void PlaceLineSegments(CurrentLine& current_line, TextSizeResult& text_size_result);
|
||||
void ForcePlaceLineSegments(CurrentLine& current_line, TextSizeResult& text_size_result, double max_width);
|
||||
void NextLine(CurrentLine& current_line);
|
||||
bool IsNewline(const TextBlock& block);
|
||||
bool IsWhitespace(const TextBlock& block);
|
||||
bool FitsOnLine(double x_position, const TextSizeResult& text_size_result, double max_width);
|
||||
bool LargerThanLine(const TextSizeResult& text_size_result, double max_width);
|
||||
void AlignJustify(double max_width);
|
||||
void AlignCenter(double max_width);
|
||||
void AlignRight(double max_width);
|
||||
void DrawLayoutImage(Canvas* canvas, Line& line, LineSegment& segment, double x, double y);
|
||||
void DrawLayoutText(Canvas* canvas, Line& line, LineSegment& segment, double x, double y);
|
||||
|
||||
bool cursor_visible = false;
|
||||
std::string::size_type cursor_pos = 0;
|
||||
bool cursor_overwrite_mode = false;
|
||||
Colorf cursor_color;
|
||||
|
||||
std::string::size_type sel_start = 0, sel_end = 0;
|
||||
Colorf sel_foreground, sel_background = Colorf::fromRgba8(153, 201, 239);
|
||||
|
||||
std::string text;
|
||||
std::vector<SpanObject> objects;
|
||||
std::vector<Line> lines;
|
||||
Point position;
|
||||
|
||||
std::vector<FloatBox> floats_left, floats_right;
|
||||
|
||||
SpanAlign alignment = span_left;
|
||||
|
||||
struct LayoutCache
|
||||
{
|
||||
int object_index = -1;
|
||||
FontMetrics metrics;
|
||||
};
|
||||
LayoutCache layout_cache;
|
||||
|
||||
bool is_ellipsis_draw = false;
|
||||
Rect ellipsis_content_rect;
|
||||
|
||||
template<typename T>
|
||||
static T clamp(T val, T minval, T maxval) { return std::max<T>(std::min<T>(val, maxval), minval); }
|
||||
};
|
||||
24
libraries/ZWidget/include/zwidget/core/timer.h
Normal file
24
libraries/ZWidget/include/zwidget/core/timer.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
class Widget;
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
Timer(Widget* owner);
|
||||
~Timer();
|
||||
|
||||
void Start(int timeoutMilliseconds, bool repeat = true);
|
||||
void Stop();
|
||||
|
||||
std::function<void()> FuncExpired;
|
||||
|
||||
private:
|
||||
Widget* OwnerObj = nullptr;
|
||||
Timer* PrevTimerObj = nullptr;
|
||||
Timer* NextTimerObj = nullptr;
|
||||
|
||||
friend class Widget;
|
||||
};
|
||||
78
libraries/ZWidget/include/zwidget/core/utf8reader.h
Normal file
78
libraries/ZWidget/include/zwidget/core/utf8reader.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
** Copyright (c) 1997-2015 Mark Page
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
**
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
/// \brief UTF8 reader helper functions.
|
||||
class UTF8Reader
|
||||
{
|
||||
public:
|
||||
/// Important: text is not copied by this class and must remain valid during its usage.
|
||||
UTF8Reader(const std::string::value_type *text, std::string::size_type length);
|
||||
|
||||
/// \brief Returns true if the current position is at the end of the string
|
||||
bool is_end();
|
||||
|
||||
/// \brief Get the character at the current position
|
||||
unsigned int character();
|
||||
|
||||
/// \brief Returns the length of the current character
|
||||
std::string::size_type char_length();
|
||||
|
||||
/// \brief Moves position to the previous character
|
||||
void prev();
|
||||
|
||||
/// \brief Moves position to the next character
|
||||
void next();
|
||||
|
||||
/// \brief Moves position to the lead byte of the character
|
||||
void move_to_leadbyte();
|
||||
|
||||
/// \brief Get the current position of the reader
|
||||
std::string::size_type position();
|
||||
|
||||
/// \brief Set the current position of the reader
|
||||
void set_position(std::string::size_type position);
|
||||
|
||||
static size_t utf8_length(const std::string& text)
|
||||
{
|
||||
return utf8_length(text.data(), text.size());
|
||||
}
|
||||
|
||||
static size_t utf8_length(const std::string::value_type* text, std::string::size_type length)
|
||||
{
|
||||
UTF8Reader reader(text, length);
|
||||
size_t i = 0;
|
||||
while (!reader.is_end())
|
||||
{
|
||||
reader.next();
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string::size_type current_position = 0;
|
||||
std::string::size_type length = 0;
|
||||
const unsigned char *data = nullptr;
|
||||
};
|
||||
181
libraries/ZWidget/include/zwidget/core/widget.h
Normal file
181
libraries/ZWidget/include/zwidget/core/widget.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "canvas.h"
|
||||
#include "rect.h"
|
||||
#include "colorf.h"
|
||||
#include "../window/window.h"
|
||||
|
||||
class Canvas;
|
||||
class Timer;
|
||||
|
||||
enum class WidgetType
|
||||
{
|
||||
Child,
|
||||
Window,
|
||||
Popup
|
||||
};
|
||||
|
||||
class Widget : DisplayWindowHost
|
||||
{
|
||||
public:
|
||||
Widget(Widget* parent = nullptr, WidgetType type = WidgetType::Child);
|
||||
virtual ~Widget();
|
||||
|
||||
void SetParent(Widget* parent);
|
||||
void MoveBefore(Widget* sibling);
|
||||
|
||||
std::string GetWindowTitle() const;
|
||||
void SetWindowTitle(const std::string& text);
|
||||
|
||||
// Icon GetWindowIcon() const;
|
||||
// void SetWindowIcon(const Icon& icon);
|
||||
|
||||
// Widget content box
|
||||
Size GetSize() const;
|
||||
double GetWidth() const { return GetSize().width; }
|
||||
double GetHeight() const { return GetSize().height; }
|
||||
|
||||
// Widget noncontent area
|
||||
void SetNoncontentSizes(double left, double top, double right, double bottom);
|
||||
|
||||
// Widget frame box
|
||||
Rect GetFrameGeometry() const;
|
||||
void SetFrameGeometry(const Rect& geometry);
|
||||
void SetFrameGeometry(double x, double y, double width, double height) { SetFrameGeometry(Rect::xywh(x, y, width, height)); }
|
||||
|
||||
void SetWindowBackground(const Colorf& color);
|
||||
void SetWindowBorderColor(const Colorf& color);
|
||||
void SetWindowCaptionColor(const Colorf& color);
|
||||
void SetWindowCaptionTextColor(const Colorf& color);
|
||||
|
||||
void SetVisible(bool enable) { if (enable) Show(); else Hide(); }
|
||||
void Show();
|
||||
void ShowFullscreen();
|
||||
void ShowMaximized();
|
||||
void ShowMinimized();
|
||||
void ShowNormal();
|
||||
void Hide();
|
||||
|
||||
void ActivateWindow();
|
||||
|
||||
void Close();
|
||||
|
||||
void Update();
|
||||
void Repaint();
|
||||
|
||||
bool HasFocus();
|
||||
bool IsEnabled();
|
||||
bool IsVisible();
|
||||
|
||||
void SetFocus();
|
||||
void SetEnabled(bool value);
|
||||
void SetDisabled(bool value) { SetEnabled(!value); }
|
||||
void SetHidden(bool value) { if (value) Hide(); else Show(); }
|
||||
|
||||
void LockCursor();
|
||||
void UnlockCursor();
|
||||
void SetCursor(StandardCursor cursor);
|
||||
void CaptureMouse();
|
||||
void ReleaseMouseCapture();
|
||||
|
||||
bool GetKeyState(EInputKey key);
|
||||
|
||||
std::string GetClipboardText();
|
||||
void SetClipboardText(const std::string& text);
|
||||
|
||||
Widget* Window();
|
||||
Canvas* GetCanvas();
|
||||
Widget* ChildAt(double x, double y) { return ChildAt(Point(x, y)); }
|
||||
Widget* ChildAt(const Point& pos);
|
||||
|
||||
Widget* Parent() const { return ParentObj; }
|
||||
Widget* PrevSibling() const { return PrevSiblingObj; }
|
||||
Widget* NextSibling() const { return NextSiblingObj; }
|
||||
Widget* FirstChild() const { return FirstChildObj; }
|
||||
Widget* LastChild() const { return LastChildObj; }
|
||||
|
||||
Point MapFrom(const Widget* parent, const Point& pos) const;
|
||||
Point MapFromGlobal(const Point& pos) const;
|
||||
Point MapFromParent(const Point& pos) const { return MapFrom(Parent(), pos); }
|
||||
|
||||
Point MapTo(const Widget* parent, const Point& pos) const;
|
||||
Point MapToGlobal(const Point& pos) const;
|
||||
Point MapToParent(const Point& pos) const { return MapTo(Parent(), pos); }
|
||||
|
||||
protected:
|
||||
virtual void OnPaintFrame(Canvas* canvas) { }
|
||||
virtual void OnPaint(Canvas* canvas) { }
|
||||
virtual void OnMouseMove(const Point& pos) { }
|
||||
virtual void OnMouseDown(const Point& pos, int key) { }
|
||||
virtual void OnMouseDoubleclick(const Point& pos, int key) { }
|
||||
virtual void OnMouseUp(const Point& pos, int key) { }
|
||||
virtual void OnMouseWheel(const Point& pos, EInputKey key) { }
|
||||
virtual void OnMouseLeave() { }
|
||||
virtual void OnRawMouseMove(int dx, int dy) { }
|
||||
virtual void OnKeyChar(std::string chars) { }
|
||||
virtual void OnKeyDown(EInputKey key) { }
|
||||
virtual void OnKeyUp(EInputKey key) { }
|
||||
virtual void OnGeometryChanged() { }
|
||||
virtual void OnClose() { delete this; }
|
||||
virtual void OnSetFocus() { }
|
||||
virtual void OnLostFocus() { }
|
||||
virtual void OnEnableChanged() { }
|
||||
|
||||
private:
|
||||
void DetachFromParent();
|
||||
|
||||
void Paint(Canvas* canvas);
|
||||
|
||||
// DisplayWindowHost
|
||||
void OnWindowPaint() override;
|
||||
void OnWindowMouseMove(const Point& pos) override;
|
||||
void OnWindowMouseDown(const Point& pos, EInputKey key) override;
|
||||
void OnWindowMouseDoubleclick(const Point& pos, EInputKey key) override;
|
||||
void OnWindowMouseUp(const Point& pos, EInputKey key) override;
|
||||
void OnWindowMouseWheel(const Point& pos, EInputKey key) override;
|
||||
void OnWindowRawMouseMove(int dx, int dy) override;
|
||||
void OnWindowKeyChar(std::string chars) override;
|
||||
void OnWindowKeyDown(EInputKey key) override;
|
||||
void OnWindowKeyUp(EInputKey key) override;
|
||||
void OnWindowGeometryChanged() override;
|
||||
void OnWindowClose() override;
|
||||
void OnWindowActivated() override;
|
||||
void OnWindowDeactivated() override;
|
||||
void OnWindowDpiScaleChanged() override;
|
||||
|
||||
WidgetType Type = {};
|
||||
|
||||
Widget* ParentObj = nullptr;
|
||||
Widget* PrevSiblingObj = nullptr;
|
||||
Widget* NextSiblingObj = nullptr;
|
||||
Widget* FirstChildObj = nullptr;
|
||||
Widget* LastChildObj = nullptr;
|
||||
|
||||
Timer* FirstTimerObj = nullptr;
|
||||
|
||||
Rect FrameGeometry = Rect::xywh(0.0, 0.0, 0.0, 0.0);
|
||||
Rect ContentGeometry = Rect::xywh(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
Colorf WindowBackground = Colorf::fromRgba8(240, 240, 240);
|
||||
|
||||
struct
|
||||
{
|
||||
double Left = 0.0;
|
||||
double Top = 0.0;
|
||||
double Right = 0.0;
|
||||
double Bottom = 0.0;
|
||||
} Noncontent;
|
||||
|
||||
std::string WindowTitle;
|
||||
std::unique_ptr<DisplayWindow> DispWindow;
|
||||
std::unique_ptr<Canvas> DispCanvas;
|
||||
Widget* FocusWidget = nullptr;
|
||||
Widget* CaptureWidget = nullptr;
|
||||
|
||||
Widget(const Widget&) = delete;
|
||||
Widget& operator=(const Widget&) = delete;
|
||||
|
||||
friend class Timer;
|
||||
};
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
|
||||
class CheckboxLabel : public Widget
|
||||
{
|
||||
public:
|
||||
CheckboxLabel(Widget* parent = nullptr);
|
||||
|
||||
void SetText(const std::string& value);
|
||||
const std::string& GetText() const;
|
||||
|
||||
void SetChecked(bool value);
|
||||
bool GetChecked() const;
|
||||
|
||||
double GetPreferredHeight() const;
|
||||
|
||||
protected:
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
|
||||
private:
|
||||
std::string text;
|
||||
bool checked = false;
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
#include "../../core/image.h"
|
||||
|
||||
class ImageBox : public Widget
|
||||
{
|
||||
public:
|
||||
ImageBox(Widget* parent);
|
||||
|
||||
void SetImage(std::shared_ptr<Image> newImage);
|
||||
|
||||
double GetPreferredHeight() const;
|
||||
|
||||
protected:
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Image> image;
|
||||
};
|
||||
160
libraries/ZWidget/include/zwidget/widgets/lineedit/lineedit.h
Normal file
160
libraries/ZWidget/include/zwidget/widgets/lineedit/lineedit.h
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
#include "../../core/timer.h"
|
||||
#include <functional>
|
||||
|
||||
class LineEdit : public Widget
|
||||
{
|
||||
public:
|
||||
LineEdit(Widget* parent);
|
||||
~LineEdit();
|
||||
|
||||
enum Alignment
|
||||
{
|
||||
align_left,
|
||||
align_center,
|
||||
align_right
|
||||
};
|
||||
|
||||
Alignment GetAlignment() const;
|
||||
bool IsReadOnly() const;
|
||||
bool IsLowercase() const;
|
||||
bool IsUppercase() const;
|
||||
bool IsPasswordMode() const;
|
||||
int GetMaxLength() const;
|
||||
|
||||
std::string GetText() const;
|
||||
int GetTextInt() const;
|
||||
float GetTextFloat() const;
|
||||
|
||||
std::string GetSelection() const;
|
||||
int GetSelectionStart() const;
|
||||
int GetSelectionLength() const;
|
||||
|
||||
int GetCursorPos() const;
|
||||
Size GetTextSize();
|
||||
|
||||
Size GetTextSize(const std::string& str);
|
||||
double GetPreferredContentWidth();
|
||||
double GetPreferredContentHeight(double width);
|
||||
|
||||
void SetSelectAllOnFocusGain(bool enable);
|
||||
void SelectAll();
|
||||
void SetAlignment(Alignment alignment);
|
||||
void SetReadOnly(bool enable = true);
|
||||
void SetLowercase(bool enable = true);
|
||||
void SetUppercase(bool enable = true);
|
||||
void SetPasswordMode(bool enable = true);
|
||||
void SetNumericMode(bool enable = true, bool decimals = false);
|
||||
void SetMaxLength(int length);
|
||||
void SetText(const std::string& text);
|
||||
void SetTextInt(int number);
|
||||
void SetTextFloat(float number, int num_decimal_places = 6);
|
||||
void SetSelection(int pos, int length);
|
||||
void ClearSelection();
|
||||
void SetCursorPos(int pos);
|
||||
void DeleteSelectedText();
|
||||
void SetInputMask(const std::string& mask);
|
||||
void SetDecimalCharacter(const std::string& decimal_char);
|
||||
|
||||
std::function<bool(int key)> FuncIgnoreKeyDown;
|
||||
std::function<std::string(std::string text)> FuncFilterKeyChar;
|
||||
std::function<void()> FuncBeforeEditChanged;
|
||||
std::function<void()> FuncAfterEditChanged;
|
||||
std::function<void()> FuncSelectionChanged;
|
||||
std::function<void()> FuncFocusGained;
|
||||
std::function<void()> FuncFocusLost;
|
||||
std::function<void()> FuncEnterPressed;
|
||||
|
||||
protected:
|
||||
void OnPaintFrame(Canvas* canvas) override;
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
void OnMouseMove(const Point& pos) override;
|
||||
void OnMouseDown(const Point& pos, int key) override;
|
||||
void OnMouseDoubleclick(const Point& pos, int key) override;
|
||||
void OnMouseUp(const Point& pos, int key) override;
|
||||
void OnKeyChar(std::string chars) override;
|
||||
void OnKeyDown(EInputKey key) override;
|
||||
void OnKeyUp(EInputKey key) override;
|
||||
void OnGeometryChanged() override;
|
||||
void OnEnableChanged() override;
|
||||
void OnSetFocus() override;
|
||||
void OnLostFocus() override;
|
||||
|
||||
private:
|
||||
void OnTimerExpired();
|
||||
void OnScrollTimerExpired();
|
||||
void UpdateTextClipping();
|
||||
|
||||
void Move(int steps, bool ctrl, bool shift);
|
||||
bool InsertText(int pos, const std::string& str);
|
||||
void Backspace();
|
||||
void Del();
|
||||
int GetCharacterIndex(double x);
|
||||
int FindNextBreakCharacter(int pos);
|
||||
int FindPreviousBreakCharacter(int pos);
|
||||
std::string GetVisibleTextBeforeSelection();
|
||||
std::string GetVisibleTextAfterSelection();
|
||||
std::string GetVisibleSelectedText();
|
||||
std::string CreatePassword(std::string::size_type num_letters) const;
|
||||
Size GetVisualTextSize(Canvas* canvas, int pos, int npos) const;
|
||||
Size GetVisualTextSize(Canvas* canvas) const;
|
||||
Rect GetCursorRect();
|
||||
Rect GetSelectionRect();
|
||||
bool InputMaskAcceptsInput(int cursor_pos, const std::string& str);
|
||||
void SetSelectionStart(int start);
|
||||
void SetSelectionLength(int length);
|
||||
void SetTextSelection(int start, int length);
|
||||
|
||||
static std::string ToFixed(float number, int num_decimal_places);
|
||||
static std::string ToLower(const std::string& text);
|
||||
static std::string ToUpper(const std::string& text);
|
||||
|
||||
Timer* timer = nullptr;
|
||||
std::string text;
|
||||
Alignment alignment = align_left;
|
||||
int cursor_pos = 0;
|
||||
int max_length = -1;
|
||||
bool mouse_selecting = false;
|
||||
bool lowercase = false;
|
||||
bool uppercase = false;
|
||||
bool password_mode = false;
|
||||
bool numeric_mode = false;
|
||||
bool numeric_mode_decimals = false;
|
||||
bool readonly = false;
|
||||
int selection_start = -1;
|
||||
int selection_length = 0;
|
||||
std::string input_mask;
|
||||
std::string decimal_char = ".";
|
||||
|
||||
VerticalTextPosition vertical_text_align;
|
||||
Timer* scroll_timer = nullptr;
|
||||
|
||||
bool mouse_moves_left = false;
|
||||
bool cursor_blink_visible = true;
|
||||
unsigned int blink_timer = 0;
|
||||
int clip_start_offset = 0;
|
||||
int clip_end_offset = 0;
|
||||
bool ignore_mouse_events = false;
|
||||
|
||||
struct UndoInfo
|
||||
{
|
||||
/* set undo text when:
|
||||
- added char after moving
|
||||
- destructive block operation (del, cut etc)
|
||||
- beginning erase
|
||||
*/
|
||||
std::string undo_text;
|
||||
bool first_erase = false;
|
||||
bool first_text_insert = false;
|
||||
};
|
||||
|
||||
UndoInfo undo_info;
|
||||
|
||||
bool select_all_on_focus_gain = true;
|
||||
|
||||
static const std::string break_characters;
|
||||
static const std::string numeric_mode_characters;
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
#include <vector>
|
||||
|
||||
class ListView : public Widget
|
||||
{
|
||||
public:
|
||||
ListView(Widget* parent = nullptr);
|
||||
|
||||
void AddItem(const std::string& text);
|
||||
|
||||
protected:
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
void OnPaintFrame(Canvas* canvas) override;
|
||||
|
||||
std::vector<std::string> items;
|
||||
};
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
|
||||
class Menubar;
|
||||
class Toolbar;
|
||||
class Statusbar;
|
||||
|
||||
class MainWindow : public Widget
|
||||
{
|
||||
public:
|
||||
MainWindow();
|
||||
~MainWindow();
|
||||
|
||||
Menubar* GetMenubar() const { return MenubarWidget; }
|
||||
Toolbar* GetToolbar() const { return ToolbarWidget; }
|
||||
Statusbar* GetStatusbar() const { return StatusbarWidget; }
|
||||
Widget* GetCentralWidget() const { return CentralWidget; }
|
||||
|
||||
void SetCentralWidget(Widget* widget);
|
||||
|
||||
protected:
|
||||
void OnGeometryChanged() override;
|
||||
|
||||
private:
|
||||
Menubar* MenubarWidget = nullptr;
|
||||
Toolbar* ToolbarWidget = nullptr;
|
||||
Widget* CentralWidget = nullptr;
|
||||
Statusbar* StatusbarWidget = nullptr;
|
||||
};
|
||||
14
libraries/ZWidget/include/zwidget/widgets/menubar/menubar.h
Normal file
14
libraries/ZWidget/include/zwidget/widgets/menubar/menubar.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
|
||||
class Menubar : public Widget
|
||||
{
|
||||
public:
|
||||
Menubar(Widget* parent);
|
||||
~Menubar();
|
||||
|
||||
protected:
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
};
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
|
||||
class PushButton : public Widget
|
||||
{
|
||||
public:
|
||||
PushButton(Widget* parent = nullptr);
|
||||
|
||||
void SetText(const std::string& value);
|
||||
const std::string& GetText() const;
|
||||
|
||||
double GetPreferredHeight() const;
|
||||
|
||||
protected:
|
||||
void OnPaintFrame(Canvas* canvas) override;
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
|
||||
private:
|
||||
std::string text;
|
||||
};
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
#include "../../core/timer.h"
|
||||
#include <functional>
|
||||
|
||||
class Scrollbar : public Widget
|
||||
{
|
||||
public:
|
||||
Scrollbar(Widget* parent);
|
||||
~Scrollbar();
|
||||
|
||||
bool IsVertical() const;
|
||||
bool IsHorizontal() const;
|
||||
int GetMin() const;
|
||||
int GetMax() const;
|
||||
int GetLineStep() const;
|
||||
int GetPageStep() const;
|
||||
int GetPosition() const;
|
||||
|
||||
void SetVertical();
|
||||
void SetHorizontal();
|
||||
|
||||
void SetMin(int scroll_min);
|
||||
void SetMax(int scroll_max);
|
||||
void SetLineStep(int step);
|
||||
void SetPageStep(int step);
|
||||
|
||||
void SetRanges(int scroll_min, int scroll_max, int line_step, int page_step);
|
||||
void SetRanges(int view_size, int total_size);
|
||||
|
||||
void SetPosition(int pos);
|
||||
|
||||
std::function<void()> FuncScroll;
|
||||
std::function<void()> FuncScrollMin;
|
||||
std::function<void()> FuncScrollMax;
|
||||
std::function<void()> FuncScrollLineDecrement;
|
||||
std::function<void()> FuncScrollLineIncrement;
|
||||
std::function<void()> FuncScrollPageDecrement;
|
||||
std::function<void()> FuncScrollPageIncrement;
|
||||
std::function<void()> FuncScrollThumbRelease;
|
||||
std::function<void()> FuncScrollThumbTrack;
|
||||
std::function<void()> FuncScrollEnd;
|
||||
|
||||
protected:
|
||||
void OnMouseMove(const Point& pos) override;
|
||||
void OnMouseDown(const Point& pos, int key) override;
|
||||
void OnMouseUp(const Point& pos, int key) override;
|
||||
void OnMouseLeave() override;
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
void OnEnableChanged() override;
|
||||
void OnGeometryChanged() override;
|
||||
|
||||
private:
|
||||
bool UpdatePartPositions();
|
||||
int CalculateThumbSize(int track_size);
|
||||
int CalculateThumbPosition(int thumb_size, int track_size);
|
||||
Rect CreateRect(int start, int end);
|
||||
void InvokeScrollEvent(std::function<void()>* event_ptr);
|
||||
void OnTimerExpired();
|
||||
|
||||
bool vertical = false;
|
||||
int scroll_min = 0;
|
||||
int scroll_max = 1;
|
||||
int line_step = 1;
|
||||
int page_step = 10;
|
||||
int position = 0;
|
||||
|
||||
enum MouseDownMode
|
||||
{
|
||||
mouse_down_none,
|
||||
mouse_down_button_decr,
|
||||
mouse_down_button_incr,
|
||||
mouse_down_track_decr,
|
||||
mouse_down_track_incr,
|
||||
mouse_down_thumb_drag
|
||||
} mouse_down_mode = mouse_down_none;
|
||||
|
||||
int thumb_start_position = 0;
|
||||
Point mouse_drag_start_pos;
|
||||
int thumb_start_pixel_position = 0;
|
||||
|
||||
Timer* mouse_down_timer = nullptr;
|
||||
int last_step_size = 0;
|
||||
|
||||
Rect rect_button_decrement;
|
||||
Rect rect_track_decrement;
|
||||
Rect rect_thumb;
|
||||
Rect rect_track_increment;
|
||||
Rect rect_button_increment;
|
||||
|
||||
std::function<void()>* FuncScrollOnMouseDown = nullptr;
|
||||
|
||||
static const int decr_height = 16;
|
||||
static const int incr_height = 16;
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
|
||||
class LineEdit;
|
||||
|
||||
class Statusbar : public Widget
|
||||
{
|
||||
public:
|
||||
Statusbar(Widget* parent);
|
||||
~Statusbar();
|
||||
|
||||
protected:
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
|
||||
private:
|
||||
LineEdit* CommandEdit = nullptr;
|
||||
};
|
||||
156
libraries/ZWidget/include/zwidget/widgets/textedit/textedit.h
Normal file
156
libraries/ZWidget/include/zwidget/widgets/textedit/textedit.h
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
#include "../../core/timer.h"
|
||||
#include "../../core/span_layout.h"
|
||||
#include "../../core/font.h"
|
||||
#include <functional>
|
||||
|
||||
class Scrollbar;
|
||||
|
||||
class TextEdit : public Widget
|
||||
{
|
||||
public:
|
||||
TextEdit(Widget* parent);
|
||||
~TextEdit();
|
||||
|
||||
bool IsReadOnly() const;
|
||||
bool IsLowercase() const;
|
||||
bool IsUppercase() const;
|
||||
int GetMaxLength() const;
|
||||
std::string GetText() const;
|
||||
int GetLineCount() const;
|
||||
std::string GetLineText(int line) const;
|
||||
std::string GetSelection() const;
|
||||
int GetSelectionStart() const;
|
||||
int GetSelectionLength() const;
|
||||
int GetCursorPos() const;
|
||||
int GetCursorLineNumber() const;
|
||||
double GetTotalHeight();
|
||||
|
||||
void SetSelectAllOnFocusGain(bool enable);
|
||||
void SelectAll();
|
||||
void SetReadOnly(bool enable = true);
|
||||
void SetLowercase(bool enable = true);
|
||||
void SetUppercase(bool enable = true);
|
||||
void SetMaxLength(int length);
|
||||
void SetText(const std::string& text);
|
||||
void AddText(const std::string& text);
|
||||
void SetSelection(int pos, int length);
|
||||
void ClearSelection();
|
||||
void SetCursorPos(int pos);
|
||||
void DeleteSelectedText();
|
||||
void SetInputMask(const std::string& mask);
|
||||
void SetCursorDrawingEnabled(bool enable);
|
||||
|
||||
std::function<std::string(std::string text)> FuncFilterKeyChar;
|
||||
std::function<void()> FuncBeforeEditChanged;
|
||||
std::function<void()> FuncAfterEditChanged;
|
||||
std::function<void()> FuncSelectionChanged;
|
||||
std::function<void()> FuncFocusGained;
|
||||
std::function<void()> FuncFocusLost;
|
||||
std::function<void()> FuncEnterPressed;
|
||||
|
||||
protected:
|
||||
void OnPaintFrame(Canvas* canvas) override;
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
void OnMouseMove(const Point& pos) override;
|
||||
void OnMouseDown(const Point& pos, int key) override;
|
||||
void OnMouseDoubleclick(const Point& pos, int key) override;
|
||||
void OnMouseUp(const Point& pos, int key) override;
|
||||
void OnKeyChar(std::string chars) override;
|
||||
void OnKeyDown(EInputKey key) override;
|
||||
void OnKeyUp(EInputKey key) override;
|
||||
void OnGeometryChanged() override;
|
||||
void OnEnableChanged() override;
|
||||
void OnSetFocus() override;
|
||||
void OnLostFocus() override;
|
||||
|
||||
private:
|
||||
void LayoutLines(Canvas* canvas);
|
||||
|
||||
void OnTimerExpired();
|
||||
void OnScrollTimerExpired();
|
||||
void CreateComponents();
|
||||
void OnVerticalScroll();
|
||||
void UpdateVerticalScroll();
|
||||
void MoveVerticalScroll();
|
||||
double GetTotalLineHeight();
|
||||
|
||||
struct Line
|
||||
{
|
||||
std::string text;
|
||||
SpanLayout layout;
|
||||
Rect box;
|
||||
bool invalidated = true;
|
||||
};
|
||||
|
||||
struct ivec2
|
||||
{
|
||||
ivec2() = default;
|
||||
ivec2(int x, int y) : x(x), y(y) { }
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
bool operator==(const ivec2& b) const { return x == b.x && y == b.y; }
|
||||
bool operator!=(const ivec2& b) const { return x != b.x || y != b.y; }
|
||||
};
|
||||
|
||||
Scrollbar* vert_scrollbar;
|
||||
Timer* timer = nullptr;
|
||||
std::vector<Line> lines = { Line() };
|
||||
ivec2 cursor_pos = { 0, 0 };
|
||||
int max_length = -1;
|
||||
bool mouse_selecting = false;
|
||||
bool lowercase = false;
|
||||
bool uppercase = false;
|
||||
bool readonly = false;
|
||||
ivec2 selection_start = { -1, 0 };
|
||||
int selection_length = 0;
|
||||
std::string input_mask;
|
||||
|
||||
static std::string break_characters;
|
||||
|
||||
void Move(int steps, bool shift, bool ctrl);
|
||||
void InsertText(ivec2 pos, const std::string& str);
|
||||
void Backspace();
|
||||
void Del();
|
||||
ivec2 GetCharacterIndex(Point mouse_wincoords);
|
||||
ivec2 FindNextBreakCharacter(ivec2 pos);
|
||||
ivec2 FindPreviousBreakCharacter(ivec2 pos);
|
||||
bool InputMaskAcceptsInput(ivec2 cursor_pos, const std::string& str);
|
||||
|
||||
std::string::size_type ToOffset(ivec2 pos) const;
|
||||
ivec2 FromOffset(std::string::size_type offset) const;
|
||||
|
||||
VerticalTextPosition vertical_text_align;
|
||||
Timer* scroll_timer = nullptr;
|
||||
|
||||
bool mouse_moves_left = false;
|
||||
bool cursor_blink_visible = true;
|
||||
unsigned int blink_timer = 0;
|
||||
int clip_start_offset = 0;
|
||||
int clip_end_offset = 0;
|
||||
bool ignore_mouse_events = false;
|
||||
|
||||
struct UndoInfo
|
||||
{
|
||||
/* set undo text when:
|
||||
- added char after moving
|
||||
- destructive block operation (del, cut etc)
|
||||
- beginning erase
|
||||
*/
|
||||
|
||||
std::string undo_text;
|
||||
bool first_erase = false;
|
||||
bool first_text_insert = false;
|
||||
} undo_info;
|
||||
|
||||
bool select_all_on_focus_gain = false;
|
||||
|
||||
std::shared_ptr<Font> font = Font::Create("Segoe UI", 12.0);
|
||||
|
||||
template<typename T>
|
||||
static T clamp(T val, T minval, T maxval) { return std::max<T>(std::min<T>(val, maxval), minval); }
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
|
||||
class TextLabel : public Widget
|
||||
{
|
||||
public:
|
||||
TextLabel(Widget* parent = nullptr);
|
||||
|
||||
void SetText(const std::string& value);
|
||||
const std::string& GetText() const;
|
||||
|
||||
double GetPreferredHeight() const;
|
||||
|
||||
protected:
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
|
||||
private:
|
||||
std::string text;
|
||||
};
|
||||
11
libraries/ZWidget/include/zwidget/widgets/toolbar/toolbar.h
Normal file
11
libraries/ZWidget/include/zwidget/widgets/toolbar/toolbar.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
|
||||
class Toolbar : public Widget
|
||||
{
|
||||
public:
|
||||
Toolbar(Widget* parent);
|
||||
~Toolbar();
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../core/widget.h"
|
||||
|
||||
class ToolbarButton : public Widget
|
||||
{
|
||||
public:
|
||||
ToolbarButton(Widget* parent);
|
||||
~ToolbarButton();
|
||||
|
||||
protected:
|
||||
void OnPaint(Canvas* canvas) override;
|
||||
};
|
||||
173
libraries/ZWidget/include/zwidget/window/window.h
Normal file
173
libraries/ZWidget/include/zwidget/window/window.h
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "../core/rect.h"
|
||||
|
||||
class Engine;
|
||||
|
||||
enum class StandardCursor
|
||||
{
|
||||
arrow,
|
||||
appstarting,
|
||||
cross,
|
||||
hand,
|
||||
ibeam,
|
||||
no,
|
||||
size_all,
|
||||
size_nesw,
|
||||
size_ns,
|
||||
size_nwse,
|
||||
size_we,
|
||||
uparrow,
|
||||
wait
|
||||
};
|
||||
|
||||
enum EInputKey
|
||||
{
|
||||
IK_None, IK_LeftMouse, IK_RightMouse, IK_Cancel,
|
||||
IK_MiddleMouse, IK_Unknown05, IK_Unknown06, IK_Unknown07,
|
||||
IK_Backspace, IK_Tab, IK_Unknown0A, IK_Unknown0B,
|
||||
IK_Unknown0C, IK_Enter, IK_Unknown0E, IK_Unknown0F,
|
||||
IK_Shift, IK_Ctrl, IK_Alt, IK_Pause,
|
||||
IK_CapsLock, IK_Unknown15, IK_Unknown16, IK_Unknown17,
|
||||
IK_Unknown18, IK_Unknown19, IK_Unknown1A, IK_Escape,
|
||||
IK_Unknown1C, IK_Unknown1D, IK_Unknown1E, IK_Unknown1F,
|
||||
IK_Space, IK_PageUp, IK_PageDown, IK_End,
|
||||
IK_Home, IK_Left, IK_Up, IK_Right,
|
||||
IK_Down, IK_Select, IK_Print, IK_Execute,
|
||||
IK_PrintScrn, IK_Insert, IK_Delete, IK_Help,
|
||||
IK_0, IK_1, IK_2, IK_3,
|
||||
IK_4, IK_5, IK_6, IK_7,
|
||||
IK_8, IK_9, IK_Unknown3A, IK_Unknown3B,
|
||||
IK_Unknown3C, IK_Unknown3D, IK_Unknown3E, IK_Unknown3F,
|
||||
IK_Unknown40, IK_A, IK_B, IK_C,
|
||||
IK_D, IK_E, IK_F, IK_G,
|
||||
IK_H, IK_I, IK_J, IK_K,
|
||||
IK_L, IK_M, IK_N, IK_O,
|
||||
IK_P, IK_Q, IK_R, IK_S,
|
||||
IK_T, IK_U, IK_V, IK_W,
|
||||
IK_X, IK_Y, IK_Z, IK_Unknown5B,
|
||||
IK_Unknown5C, IK_Unknown5D, IK_Unknown5E, IK_Unknown5F,
|
||||
IK_NumPad0, IK_NumPad1, IK_NumPad2, IK_NumPad3,
|
||||
IK_NumPad4, IK_NumPad5, IK_NumPad6, IK_NumPad7,
|
||||
IK_NumPad8, IK_NumPad9, IK_GreyStar, IK_GreyPlus,
|
||||
IK_Separator, IK_GreyMinus, IK_NumPadPeriod, IK_GreySlash,
|
||||
IK_F1, IK_F2, IK_F3, IK_F4,
|
||||
IK_F5, IK_F6, IK_F7, IK_F8,
|
||||
IK_F9, IK_F10, IK_F11, IK_F12,
|
||||
IK_F13, IK_F14, IK_F15, IK_F16,
|
||||
IK_F17, IK_F18, IK_F19, IK_F20,
|
||||
IK_F21, IK_F22, IK_F23, IK_F24,
|
||||
IK_Unknown88, IK_Unknown89, IK_Unknown8A, IK_Unknown8B,
|
||||
IK_Unknown8C, IK_Unknown8D, IK_Unknown8E, IK_Unknown8F,
|
||||
IK_NumLock, IK_ScrollLock, IK_Unknown92, IK_Unknown93,
|
||||
IK_Unknown94, IK_Unknown95, IK_Unknown96, IK_Unknown97,
|
||||
IK_Unknown98, IK_Unknown99, IK_Unknown9A, IK_Unknown9B,
|
||||
IK_Unknown9C, IK_Unknown9D, IK_Unknown9E, IK_Unknown9F,
|
||||
IK_LShift, IK_RShift, IK_LControl, IK_RControl,
|
||||
IK_UnknownA4, IK_UnknownA5, IK_UnknownA6, IK_UnknownA7,
|
||||
IK_UnknownA8, IK_UnknownA9, IK_UnknownAA, IK_UnknownAB,
|
||||
IK_UnknownAC, IK_UnknownAD, IK_UnknownAE, IK_UnknownAF,
|
||||
IK_UnknownB0, IK_UnknownB1, IK_UnknownB2, IK_UnknownB3,
|
||||
IK_UnknownB4, IK_UnknownB5, IK_UnknownB6, IK_UnknownB7,
|
||||
IK_UnknownB8, IK_UnknownB9, IK_Semicolon, IK_Equals,
|
||||
IK_Comma, IK_Minus, IK_Period, IK_Slash,
|
||||
IK_Tilde, IK_UnknownC1, IK_UnknownC2, IK_UnknownC3,
|
||||
IK_UnknownC4, IK_UnknownC5, IK_UnknownC6, IK_UnknownC7,
|
||||
IK_Joy1, IK_Joy2, IK_Joy3, IK_Joy4,
|
||||
IK_Joy5, IK_Joy6, IK_Joy7, IK_Joy8,
|
||||
IK_Joy9, IK_Joy10, IK_Joy11, IK_Joy12,
|
||||
IK_Joy13, IK_Joy14, IK_Joy15, IK_Joy16,
|
||||
IK_UnknownD8, IK_UnknownD9, IK_UnknownDA, IK_LeftBracket,
|
||||
IK_Backslash, IK_RightBracket, IK_SingleQuote, IK_UnknownDF,
|
||||
IK_JoyX, IK_JoyY, IK_JoyZ, IK_JoyR,
|
||||
IK_MouseX, IK_MouseY, IK_MouseZ, IK_MouseW,
|
||||
IK_JoyU, IK_JoyV, IK_UnknownEA, IK_UnknownEB,
|
||||
IK_MouseWheelUp, IK_MouseWheelDown, IK_Unknown10E, IK_Unknown10F,
|
||||
IK_JoyPovUp, IK_JoyPovDown, IK_JoyPovLeft, IK_JoyPovRight,
|
||||
IK_UnknownF4, IK_UnknownF5, IK_Attn, IK_CrSel,
|
||||
IK_ExSel, IK_ErEof, IK_Play, IK_Zoom,
|
||||
IK_NoName, IK_PA1, IK_OEMClear
|
||||
};
|
||||
|
||||
enum EInputType
|
||||
{
|
||||
IST_None,
|
||||
IST_Press,
|
||||
IST_Hold,
|
||||
IST_Release,
|
||||
IST_Axis
|
||||
};
|
||||
|
||||
class KeyEvent
|
||||
{
|
||||
public:
|
||||
EInputKey Key;
|
||||
bool Ctrl = false;
|
||||
bool Alt = false;
|
||||
bool Shift = false;
|
||||
Point MousePos = Point(0.0, 0.0);
|
||||
};
|
||||
|
||||
class DisplayWindow;
|
||||
|
||||
class DisplayWindowHost
|
||||
{
|
||||
public:
|
||||
virtual void OnWindowPaint() = 0;
|
||||
virtual void OnWindowMouseMove(const Point& pos) = 0;
|
||||
virtual void OnWindowMouseDown(const Point& pos, EInputKey key) = 0;
|
||||
virtual void OnWindowMouseDoubleclick(const Point& pos, EInputKey key) = 0;
|
||||
virtual void OnWindowMouseUp(const Point& pos, EInputKey key) = 0;
|
||||
virtual void OnWindowMouseWheel(const Point& pos, EInputKey key) = 0;
|
||||
virtual void OnWindowRawMouseMove(int dx, int dy) = 0;
|
||||
virtual void OnWindowKeyChar(std::string chars) = 0;
|
||||
virtual void OnWindowKeyDown(EInputKey key) = 0;
|
||||
virtual void OnWindowKeyUp(EInputKey key) = 0;
|
||||
virtual void OnWindowGeometryChanged() = 0;
|
||||
virtual void OnWindowClose() = 0;
|
||||
virtual void OnWindowActivated() = 0;
|
||||
virtual void OnWindowDeactivated() = 0;
|
||||
virtual void OnWindowDpiScaleChanged() = 0;
|
||||
};
|
||||
|
||||
class DisplayWindow
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<DisplayWindow> Create(DisplayWindowHost* windowHost);
|
||||
|
||||
static void ProcessEvents();
|
||||
static void RunLoop();
|
||||
static void ExitLoop();
|
||||
|
||||
virtual ~DisplayWindow() = default;
|
||||
|
||||
virtual void SetWindowTitle(const std::string& text) = 0;
|
||||
virtual void SetWindowFrame(const Rect& box) = 0;
|
||||
virtual void SetClientFrame(const Rect& box) = 0;
|
||||
virtual void Show() = 0;
|
||||
virtual void ShowFullscreen() = 0;
|
||||
virtual void ShowMaximized() = 0;
|
||||
virtual void ShowMinimized() = 0;
|
||||
virtual void ShowNormal() = 0;
|
||||
virtual void Hide() = 0;
|
||||
virtual void Activate() = 0;
|
||||
virtual void ShowCursor(bool enable) = 0;
|
||||
virtual void LockCursor() = 0;
|
||||
virtual void UnlockCursor() = 0;
|
||||
virtual void Update() = 0;
|
||||
virtual bool GetKeyState(EInputKey key) = 0;
|
||||
|
||||
virtual Rect GetWindowFrame() const = 0;
|
||||
virtual Size GetClientSize() const = 0;
|
||||
virtual int GetPixelWidth() const = 0;
|
||||
virtual int GetPixelHeight() const = 0;
|
||||
virtual double GetDpiScale() const = 0;
|
||||
|
||||
virtual void SetBorderColor(uint32_t bgra8) = 0;
|
||||
virtual void SetCaptionColor(uint32_t bgra8) = 0;
|
||||
virtual void SetCaptionTextColor(uint32_t bgra8) = 0;
|
||||
|
||||
virtual void PresentBitmap(int width, int height, const uint32_t* pixels) = 0;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue