#include "RectangleElement.h" #include "Widget.h" #include Widget::Widget() : mLocation(DiscretePoint(0, 0)), mSize({100, 0, 0, 100, 0, 0}), mPadding(), mMargin(), mMyLayers(), mLayers(), mChildren(), mBorderThickness(0), mBackgroundColor(Color::Create(255, 255, 255)), mBorderColor(Color::Create(0, 0, 0)), mVisible(true) { } Widget::~Widget() { } std::unique_ptr Widget::Create() { return std::make_unique(); } void Widget::AddWidget(WidgetUPtr widget) { mChildren.push_back(std::move(widget)); } Widget::BoundedSize Widget::GetSize() const { return mSize; } DiscretePoint Widget::GetLocation() const { return mLocation; } std::vector Widget::GetLayers() const { return mLayers; } void Widget::SetSize(const BoundedSize& size) { mSize = size; } void Widget::SetMargin(unsigned margin) { mMargin = {margin, margin, margin, margin}; } void Widget::SetMargin(const BoundaryOffset& margin) { mMargin = margin; } void Widget::SetPadding(unsigned padding) { mPadding = {padding, padding, padding, padding}; } void Widget::SetPadding(const BoundaryOffset& padding) { mPadding = padding; } void Widget::CopyMyLayers() { mLayers.clear(); mLayers.reserve(mMyLayers.size()); auto getRaw = [](const VisualLayerUPtr& uptr){return uptr.get();}; std::transform(mMyLayers.begin(), mMyLayers.end(), std::back_inserter(mLayers), getRaw); } void Widget::SetBounds(unsigned width, unsigned height) { mSize.mWidth = width; mSize.mHeight = height; } void Widget::AddChildLayers(const PaintEvent* event) { for(auto& child: mChildren) { child->SetBounds(mSize.mWidth, mSize.mHeight); child->SetLocation(mLocation); child->OnPaintEvent(event); const auto layers = child->GetLayers(); mLayers.insert(mLayers.end(), layers.begin(), layers.end()); } } void Widget::OnPaintEvent(const PaintEvent* event) { mMyLayers.clear(); mLayers.clear(); if(!mVisible)return; AddBackground(event); CopyMyLayers(); AddChildLayers(event); } bool Widget::Contains(const DiscretePoint& loc) const { if(loc.GetX() < mLocation.GetX()) return false; if(loc.GetX() > mLocation.GetX() + mSize.mWidth) return false; if(loc.GetY() > mLocation.GetY() + mSize.mHeight) return false; if(loc.GetY() < mLocation.GetY()) return false; return true; } bool Widget::OnKeyboardEvent(const KeyboardEvent* event) { bool inChild = false; for(const auto& child : mChildren) { if(child->OnKeyboardEvent(event)) { inChild = true; break; } } if(!inChild) { return OnMyKeyboardEvent(event); } return true; } bool Widget::OnMyKeyboardEvent(const KeyboardEvent* event) { return false; } bool Widget::OnMouseEvent(const MouseEvent* event) { bool inChild = false; for(const auto& child : mChildren) { if(child->OnMouseEvent(event)) { inChild = true; break; } } if(!inChild) { if(Contains(event->GetClientLocation())) { OnMyMouseEvent(event); return true; } else { return false; } } return true; } void Widget::OnMyMouseEvent(const MouseEvent* event) { } void Widget::AddBackground(const PaintEvent* event) { unsigned locX = mLocation.GetX() + mMargin.mLeft; unsigned locY = mLocation.GetY() + mMargin.mTop; unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight; unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom; auto shape = RectangleElement::Create(DiscretePoint(locX, locY), deltaX, deltaY); shape->SetFillColor(Color::Create(*mBackgroundColor)); auto shapeLayer = VisualLayer::Create(); shapeLayer->SetShape(std::move(shape)); mMyLayers.push_back(std::move(shapeLayer)); } void Widget::SetBackgroundColor(ColorUPtr color) { mBackgroundColor = std::move(color); } void Widget::SetLocation(const DiscretePoint& loc) { mLocation = loc; } void Widget::SetVisible(bool visible) { mVisible = visible; }