#include "gui/Widget.hpp"
#include <cstdint>
using namespace gui;
Position
gui::operator-(const Position &lhs, const Position &rhs)
{
return { lhs.x - rhs.x, lhs.y - rhs.y };
}
Position &
gui::operator+=(Position &lhs, const Position &rhs)
{
lhs.x += rhs.x;
lhs.y += rhs.y;
return lhs;
}
Widget::Widget(Widget *parent, Position pos, Dimentions size, Color color)
: parent(parent), pos(pos), size(size), color(color), focusable(false)
{
}
void
Widget::focus(Widget &widget)
{
if (parent != nullptr) {
parent->focus(widget);
}
}
Position
Widget::modelToScreen(Position p)
{
if (parent != nullptr) {
p = parent->modelToScreen(p);
}
p.x += pos.x;
p.y += pos.y;
return p;
}
bool
Widget::containsCoordinate(Position p)
{
return p.x >= pos.x
&& p.y >= pos.y
&& p.x < pos.x + size.w
&& p.y < pos.y + size.h;
}
void
Widget::draw(GraphicsContext &gc)
{
Position p = modelToScreen({ 0, 0 });
gc.fillRectangle(drv::Position { p.x, p.y },
drv::Dimentions { size.w, size.h },
drv::Color { color.r, color.g, color.b });
}
void
Widget::onMouseDown(Position /*p*/, std::uint8_t /*button*/)
{
if (focusable) {
focus(*this);
}
}
void
Widget::onMouseUp(Position /*p*/, std::uint8_t /*button*/)
{
}
void
Widget::onMouseMove(Position /*oldPos*/, Position /*newPos*/)
{
}
CompositeWidget::CompositeWidget(Widget *parent, Position pos, Dimentions size,
Color color)
: Widget(parent, pos, size, color)
{
focusedChild = nullptr;
numChildren = 0;
}
bool
CompositeWidget::addChild(Widget &child)
{
if (&child == this) {
return false;
}
if (numChildren == 100) {
return false;
}
children[numChildren++] = &child;
return true;
}
void
CompositeWidget::focus(Widget &widget)
{
focusedChild = &widget;
if (parent != nullptr) {
parent->focus(*this);
}
}
void
CompositeWidget::draw(GraphicsContext &gc)
{
Widget::draw(gc);
for (int i = numChildren - 1; i >= 0; --i) {
children[i]->draw(gc);
}
}
void
CompositeWidget::onMouseDown(Position p, std::uint8_t button)
{
Position rp = p - pos;
for (int i = 0; i < numChildren; ++i) {
if (children[i]->containsCoordinate(rp)) {
children[i]->onMouseDown(rp, button);
break;
}
}
}
void
CompositeWidget::onMouseUp(Position p, std::uint8_t button)
{
Position rp = p - pos;
for (int i = 0; i < numChildren; ++i) {
if (children[i]->containsCoordinate(rp)) {
children[i]->onMouseUp(rp, button);
break;
}
}
}
void
CompositeWidget::onMouseMove(Position oldPos, Position newPos)
{
Position rOldPos = oldPos - pos;
Position rNewPos = newPos - pos;
int firstchild = -1;
for (int i = 0; i < numChildren; ++i) {
if (children[i]->containsCoordinate(rOldPos)) {
children[i]->onMouseMove(rOldPos, rNewPos);
firstchild = i;
break;
}
}
for (int i = 0; i < numChildren; ++i) {
if (children[i]->containsCoordinate(rNewPos)) {
if (firstchild != i) {
children[i]->onMouseMove(rOldPos, rNewPos);
}
break;
}
}
}
void
CompositeWidget::onKeyDown(std::uint8_t scanCode)
{
if (focusedChild != nullptr) {
focusedChild->onKeyDown(scanCode);
}
}
void
CompositeWidget::onKeyUp(std::uint8_t scanCode)
{
if (focusedChild != nullptr) {
focusedChild->onKeyUp(scanCode);
}
}
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"
Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/tos
Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/tos
You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a
pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master