Replace Old Widgets
This commit is contained in:
parent
cce8f0e1bc
commit
fcd5eb2d2a
81 changed files with 388 additions and 278 deletions
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
#include "ChatGUI.hpp"
|
||||
|
||||
#include "GraphicApplication.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
class ExampleGUI : public Application {
|
||||
public:
|
||||
ExampleGUI() = default;
|
||||
|
||||
void processFrame(EventHandler* eventHandler, halnf delta) override {
|
||||
auto rec = RectF({ 0, 0 }, mWindow->getSize());
|
||||
|
||||
mGui.updateConfigWrapper(mWidgetManager);
|
||||
mGui.setArea(rec);
|
||||
mGui.setVisible(true);
|
||||
|
||||
mGui.procWrapper(*eventHandler, rec);
|
||||
}
|
||||
|
||||
void drawFrame(Canvas* canvas) override { mGui.drawWrapper(*canvas); }
|
||||
|
||||
private:
|
||||
WidgetManager mWidgetManager;
|
||||
ComplexWidget mGui;
|
||||
};
|
||||
|
||||
int main() {
|
||||
{
|
||||
ExampleGUI gui;
|
||||
gui.run();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,256 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Widgets.hpp"
|
||||
|
||||
namespace tp {
|
||||
|
||||
class UserWidget : public Widget {
|
||||
public:
|
||||
UserWidget() = default;
|
||||
|
||||
void eventDraw(Canvas& canvas) override {
|
||||
if (this->isFocus()) canvas.rect(this->mArea, mAccentColor, mRounding);
|
||||
else canvas.rect(this->mArea, mBaseColor, mRounding);
|
||||
canvas.text(mUser.c_str(), this->mArea, mFontSize, Canvas::CC, mPadding, mUserColor);
|
||||
}
|
||||
|
||||
public:
|
||||
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||
wm.setActiveId("UserWidget");
|
||||
|
||||
mBaseColor = wm.getColor("Base", "Base");
|
||||
mFontSize = wm.getNumber("Size", "FontSize");
|
||||
mPadding = wm.getNumber("Padding", "Padding");
|
||||
mUserColor = wm.getColor("ColUser", "Front");
|
||||
mAccentColor = wm.getColor("Accent", "Accent");
|
||||
mRounding = wm.getNumber("Rounding", "Rounding");
|
||||
}
|
||||
|
||||
public:
|
||||
std::string mUser = "UserName";
|
||||
bool mIsHover = false;
|
||||
|
||||
RGBA mBaseColor;
|
||||
RGBA mUserColor;
|
||||
RGBA mAccentColor;
|
||||
halnf mPadding = 0;
|
||||
halnf mFontSize = 0;
|
||||
halnf mRounding = 0;
|
||||
};
|
||||
|
||||
class MessageWidget : public Widget {
|
||||
public:
|
||||
MessageWidget() = default;
|
||||
|
||||
void eventDraw(Canvas& canvas) override {
|
||||
if (this->isFocus()) canvas.rect(this->mArea, mBaseColor, mRounding);
|
||||
|
||||
auto userName = this->mArea;
|
||||
userName.w = 25;
|
||||
|
||||
auto content = this->mArea;
|
||||
content.y = userName.y + userName.w;
|
||||
content.w = this->mArea.w - userName.w;
|
||||
|
||||
canvas.text(mContent.c_str(), content, mFontSize, Canvas::LC, mPadding, mUserColorDim);
|
||||
canvas.text(mUser.c_str(), userName, mFontSizeDim, Canvas::LC, mPadding, mUserColor);
|
||||
}
|
||||
|
||||
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||
wm.setActiveId("MessageWidget");
|
||||
|
||||
mBaseColor = wm.getColor("Base", "Base");
|
||||
mFontSize = wm.getNumber("Size", "FontSize");
|
||||
mFontSizeDim = wm.getNumber("SizeUser", "FontSizeDim");
|
||||
mPadding = wm.getNumber("Padding", "Padding");
|
||||
mUserColor = wm.getColor("UserColor", "Front");
|
||||
mUserColorDim = wm.getColor("UserColorDim", "FrontDim");
|
||||
mRounding = wm.getNumber("Rounding", "Rounding");
|
||||
}
|
||||
|
||||
public:
|
||||
std::string mContent = "Message Content";
|
||||
std::string mUser = "UserName";
|
||||
bool mIsHover = false;
|
||||
|
||||
RGBA mBaseColor;
|
||||
RGBA mUserColor;
|
||||
RGBA mUserColorDim;
|
||||
halnf mPadding = 0;
|
||||
halnf mFontSize = 0;
|
||||
halnf mFontSizeDim = 0;
|
||||
halnf mRounding = 0;
|
||||
};
|
||||
|
||||
class LoginWidget : public Widget {
|
||||
public:
|
||||
explicit LoginWidget() {
|
||||
mPass.mId = "pass";
|
||||
mUser.mId = "user";
|
||||
mButton.mLabel.mLabel = "Login";
|
||||
|
||||
this->mChildWidgets.pushBack(&mPass);
|
||||
this->mChildWidgets.pushBack(&mUser);
|
||||
this->mChildWidgets.pushBack(&mButton);
|
||||
}
|
||||
|
||||
void eventProcess(const Events& events) override {
|
||||
mLogged = false;
|
||||
|
||||
const auto xval = this->mArea.z / 2 - 100;
|
||||
|
||||
mUser.setArea({ xval, 10, 200, 30 });
|
||||
mPass.setArea({ xval, 50, 200, 30 });
|
||||
mButton.setArea({ xval, 90, 200, 30 });
|
||||
|
||||
if (mButton.isFired()) {
|
||||
mLogged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, mBGColor); }
|
||||
|
||||
public:
|
||||
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||
wm.setActiveId("LoginWidget");
|
||||
mBGColor = wm.getColor("Back", "Base");
|
||||
}
|
||||
|
||||
public:
|
||||
TextInputWidget mUser;
|
||||
TextInputWidget mPass;
|
||||
ButtonWidget mButton;
|
||||
bool mLogged = false;
|
||||
|
||||
RGBA mBGColor;
|
||||
};
|
||||
|
||||
class ActiveChatWidget : public Widget {
|
||||
public:
|
||||
ActiveChatWidget() {
|
||||
mSend.mLabel.mLabel = "Send";
|
||||
mMessage.mId = "Message";
|
||||
|
||||
this->mChildWidgets.pushBack(&mHistoryView);
|
||||
this->mChildWidgets.pushBack(&mMessage);
|
||||
this->mChildWidgets.pushBack(&mSend);
|
||||
}
|
||||
|
||||
void eventProcess(const Events& events) override {
|
||||
auto history = this->mArea;
|
||||
history.w -= 50;
|
||||
|
||||
auto input = this->mArea;
|
||||
input.y = history.w + 10;
|
||||
input.w = 40 - mPadding;
|
||||
input.x += mPadding;
|
||||
input.z -= mPadding;
|
||||
|
||||
auto inputMessage = input;
|
||||
inputMessage.z -= 100;
|
||||
|
||||
auto inputSend = input;
|
||||
inputSend.x = inputMessage.x + inputMessage.z + mPadding;
|
||||
inputSend.z = 100 - mPadding * 2;
|
||||
|
||||
mSend.setArea(inputSend);
|
||||
mMessage.setArea(inputMessage);
|
||||
|
||||
mHistoryView.setArea(history);
|
||||
}
|
||||
|
||||
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, mBGColor); }
|
||||
|
||||
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||
wm.setActiveId("ActiveChat");
|
||||
mBGColor = wm.getColor("Back", "Background");
|
||||
mPadding = wm.getNumber("Padding", "Padding");
|
||||
}
|
||||
|
||||
public:
|
||||
Buffer<MessageWidget> mMessages;
|
||||
ScrollableWindow mHistoryView;
|
||||
TextInputWidget mMessage;
|
||||
ButtonWidget mSend;
|
||||
|
||||
RGBA mBGColor;
|
||||
halnf mPadding = 0;
|
||||
};
|
||||
|
||||
class ChattingWidget : public DockWidget {
|
||||
public:
|
||||
ChattingWidget() {
|
||||
// todo : fetch code
|
||||
mUsers.append(UserWidget());
|
||||
mUsers.append(UserWidget());
|
||||
mUsers.append(UserWidget());
|
||||
|
||||
mUsers[0].mArea = { 0, 0, 100, 100 };
|
||||
mUsers[1].mArea = { 0, 0, 100, 100 };
|
||||
mUsers[2].mArea = { 0, 0, 100, 100 };
|
||||
|
||||
for (auto message : mUsers) {
|
||||
mSideView.addWidget(&message.data());
|
||||
}
|
||||
|
||||
mActive.mMessages.append(MessageWidget());
|
||||
mActive.mMessages.append(MessageWidget());
|
||||
mActive.mMessages.append(MessageWidget());
|
||||
|
||||
mActive.mMessages[0].mArea = { 0, 0, 100, 50 };
|
||||
mActive.mMessages[1].mArea = { 0, 0, 100, 50 };
|
||||
mActive.mMessages[2].mArea = { 0, 0, 100, 50 };
|
||||
|
||||
for (auto message : mActive.mMessages) {
|
||||
mActive.mHistoryView.addWidget(&message.data());
|
||||
}
|
||||
|
||||
addSideWidget(&mSideView, DockWidget::RIGHT);
|
||||
setCenterWidget(&mActive);
|
||||
}
|
||||
|
||||
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||
wm.setActiveId("ChattingWidget");
|
||||
mBGColor = wm.getColor("Back", "Background");
|
||||
}
|
||||
|
||||
public:
|
||||
Buffer<UserWidget> mUsers;
|
||||
ScrollableWindow mSideView;
|
||||
ActiveChatWidget mActive;
|
||||
|
||||
RGBA mBGColor;
|
||||
};
|
||||
|
||||
class ComplexWidget : public Widget {
|
||||
public:
|
||||
ComplexWidget() {
|
||||
this->mChildWidgets.pushBack(&mLogin);
|
||||
this->mChildWidgets.pushBack(&mChatting);
|
||||
}
|
||||
|
||||
void eventProcess(const Events& events) override {
|
||||
mLogged = mLogin.mLogged;
|
||||
|
||||
mLogin.setEnable(!mLogged);
|
||||
mChatting.setEnable(mLogged);
|
||||
|
||||
mLogin.setArea(this->mArea);
|
||||
mChatting.setArea(this->mArea);
|
||||
}
|
||||
|
||||
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, mBGColor); }
|
||||
|
||||
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||
wm.setActiveId("ChatGui");
|
||||
mBGColor = wm.getColor("Back", "Background");
|
||||
}
|
||||
|
||||
private:
|
||||
bool mLogged = false;
|
||||
LoginWidget mLogin;
|
||||
ChattingWidget mChatting;
|
||||
|
||||
RGBA mBGColor;
|
||||
};
|
||||
}
|
||||
213
Widgets/examples/Example.cpp
Normal file
213
Widgets/examples/Example.cpp
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
|
||||
#include "WidgetApplication.hpp"
|
||||
|
||||
#include "RootWidget.hpp"
|
||||
#include "FloatingWidget.hpp"
|
||||
#include "DockWidget.hpp"
|
||||
|
||||
#include "ScrollableLayout.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
|
||||
class Example : public WidgetApplication {
|
||||
public:
|
||||
Example() {
|
||||
exampleScrolling();
|
||||
}
|
||||
|
||||
void exampleAll() {
|
||||
static DockWidget dock;
|
||||
static LabelWidget centralWidget;
|
||||
static FloatingMenu menus[4];
|
||||
static FloatingMenu nestedMenus[4];
|
||||
static FloatingMenu buttons[10];
|
||||
|
||||
dock.setCenterWidget(¢ralWidget);
|
||||
|
||||
for (auto& menu : menus) {
|
||||
dock.addChild(&menu);
|
||||
}
|
||||
|
||||
for (auto& menu : nestedMenus) {
|
||||
menus[0].addToMenu(&menu);
|
||||
}
|
||||
|
||||
setRoot(&dock);
|
||||
}
|
||||
|
||||
void exampleBasic() {
|
||||
static Widget widget;
|
||||
static LabelWidget label;
|
||||
static SliderWidget slider;
|
||||
static ButtonWidget button;
|
||||
|
||||
widget.addChild(&label);
|
||||
widget.addChild(&button);
|
||||
widget.addChild(&slider);
|
||||
|
||||
setRoot(&widget);
|
||||
}
|
||||
|
||||
void exampleScrolling() {
|
||||
static Widget widget;
|
||||
static Widget content;
|
||||
static ButtonWidget buttons[10];
|
||||
static ScrollableBarWidget scrollBar;
|
||||
|
||||
setRoot(&widget);
|
||||
|
||||
widget.addChild(&scrollBar);
|
||||
widget.addChild(&content);
|
||||
|
||||
for (auto& button : buttons) {
|
||||
content.addChild(&button);
|
||||
}
|
||||
|
||||
widget.setLayout(new ScrollableLayout(&widget));
|
||||
|
||||
RootWidget::setWidgetArea(content, { 333, 333, 522, 522 });
|
||||
}
|
||||
|
||||
void examplePopup() {
|
||||
static Widget root;
|
||||
static ButtonWidget closeButton;
|
||||
static ButtonWidget openButton;
|
||||
|
||||
root.addChild(&openButton);
|
||||
((BasicLayout*)root.getLayout())->setLayoutPolicy(LayoutPolicy::Passive);
|
||||
|
||||
openButton.setAction([&](){
|
||||
closeButton.setArea({ 50, 50, 100, 100 });
|
||||
openButton.openPopup(&closeButton);
|
||||
});
|
||||
|
||||
closeButton.setAction([&](){
|
||||
closeButton.closePopup(&closeButton);
|
||||
});
|
||||
|
||||
openButton.setText("open");
|
||||
closeButton.setText("close");
|
||||
|
||||
RootWidget::setWidgetArea(openButton, { 333, 333, 222, 222 });
|
||||
|
||||
setRoot(&root);
|
||||
}
|
||||
|
||||
void exampleNestedMenus() {
|
||||
static DockWidget dock;
|
||||
static FloatingMenu menu1;
|
||||
static FloatingMenu menu2;
|
||||
static ButtonWidget buttons[15];
|
||||
|
||||
setRoot(&dock);
|
||||
|
||||
dock.addChild(&menu1);
|
||||
dock.addChild(&menu2);
|
||||
|
||||
dock.setCenterWidget(&buttons[5]);
|
||||
dock.dockWidget(&buttons[6], DockLayout::RIGHT);
|
||||
|
||||
menu1.addToMenu(&buttons[0]);
|
||||
|
||||
menu2.addToMenu(&buttons[2]);
|
||||
menu2.addToMenu(&buttons[3]);
|
||||
menu2.addToMenu(&buttons[4]);
|
||||
|
||||
menu2.addToMenu(&menu1);
|
||||
|
||||
// popup
|
||||
{
|
||||
buttons[0].setAction([&](){
|
||||
buttons[10].setArea({ 30, 30, 100, 100 });
|
||||
buttons[0].openPopup(&buttons[10]);
|
||||
});
|
||||
|
||||
buttons[0].setText("open popup");
|
||||
|
||||
buttons[10].setAction([&](){
|
||||
buttons[10].closePopup(&buttons[10]);
|
||||
});
|
||||
|
||||
buttons[10].setText("close popup");
|
||||
}
|
||||
|
||||
RootWidget::setWidgetArea(menu1, { 300, 100, 150, 500 });
|
||||
RootWidget::setWidgetArea(menu2, { 100, 100, 150, 300 });
|
||||
}
|
||||
|
||||
void exampleLayouts() {
|
||||
static Widget widgets[15];
|
||||
static ButtonWidget buttons[15];
|
||||
|
||||
setRoot(&widgets[0]);
|
||||
|
||||
widgets[0].addChild(&widgets[1]);
|
||||
|
||||
widgets[1].addChild(&buttons[1]);
|
||||
widgets[1].addChild(&buttons[2]);
|
||||
widgets[1].addChild(&widgets[2]);
|
||||
|
||||
RootWidget::setWidgetArea(buttons[1], { 300, 100, 350, 800 });
|
||||
RootWidget::setWidgetArea(buttons[2], { 100, 100, 150, 300 });
|
||||
|
||||
widgets[2].addChild(&buttons[3]);
|
||||
widgets[2].addChild(&buttons[4]);
|
||||
widgets[2].addChild(&buttons[5]);
|
||||
widgets[2].addChild(&buttons[6]);
|
||||
|
||||
buttons[1].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||
buttons[2].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||
buttons[3].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||
buttons[4].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||
buttons[5].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||
buttons[6].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||
|
||||
widgets[2].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||
((BasicLayout*)widgets[1].getLayout())->setLayoutPolicy(LayoutPolicy::Horizontal);
|
||||
}
|
||||
|
||||
void exampleDock() {
|
||||
static DockWidget dock;
|
||||
static FloatingMenu menu1;
|
||||
static FloatingMenu menu2;
|
||||
static ButtonWidget buttons[15];
|
||||
|
||||
setRoot(&dock);
|
||||
|
||||
dock.addChild(&menu2);
|
||||
dock.addChild(&menu1);
|
||||
|
||||
dock.setCenterWidget(&buttons[5]);
|
||||
dock.dockWidget(&buttons[6], DockLayout::RIGHT);
|
||||
|
||||
menu1.addToMenu(&buttons[0]);
|
||||
menu2.addToMenu(&buttons[2]);
|
||||
//menu2.addToMenu(&menu1);
|
||||
menu2.addToMenu(&buttons[3]);
|
||||
menu2.addToMenu(&buttons[4]);
|
||||
|
||||
buttons[0].setAction([&]() { buttons[2].setColor(RGBA::random()); });
|
||||
buttons[2].setAction([&]() { buttons[0].setColor(RGBA::random()); });
|
||||
|
||||
buttons[5].setAction([&]() { dock.dockWidget(&menu1, DockLayout::LEFT); });
|
||||
buttons[6].setAction([&]() { dock.undockWidget(DockLayout::LEFT); });
|
||||
|
||||
buttons[3].setAction([&]() { dock.toggleWidgetVisibility(DockLayout::LEFT); });
|
||||
// buttons[4].setAction([this]() { mDockLayout.undockWidget(DockLayout::LEFT); });
|
||||
|
||||
buttons[3].setText("toggle");
|
||||
buttons[5].setText("dock");
|
||||
buttons[6].setText("undock");
|
||||
|
||||
RootWidget::setWidgetArea(menu2, { 300, 100, 150, 500 });
|
||||
RootWidget::setWidgetArea(menu1, { 100, 100, 150, 300 });
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
{
|
||||
Example gui;
|
||||
gui.run();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
|
||||
#include "SimpleGUI.hpp"
|
||||
|
||||
#include "GraphicApplication.hpp"
|
||||
|
||||
|
||||
using namespace tp;
|
||||
|
||||
class SimpleGUI : public Application {
|
||||
public:
|
||||
SimpleGUI() {
|
||||
// mGui.mPreview = true;
|
||||
}
|
||||
|
||||
void processFrame(EventHandler* eventHandler, halnf) override {
|
||||
const auto rec = RectF({ 0, 0 }, mWindow->getSize());
|
||||
|
||||
mGui.setArea(rec);
|
||||
mGui.updateConfigWrapper(mWidgetManager);
|
||||
mGui.procWrapper(*eventHandler, rec);
|
||||
}
|
||||
|
||||
void drawFrame(Canvas* canvas) override {
|
||||
canvas->rect(mGui.mArea, { 0.1f, 0.1f, 0.1f, 1.f });
|
||||
mGui.drawWrapper(*canvas);
|
||||
}
|
||||
|
||||
private:
|
||||
WidgetManager mWidgetManager;
|
||||
|
||||
// DockSpaceWidget mGui;
|
||||
SimpleWidget3 mGui;
|
||||
};
|
||||
|
||||
int main() {
|
||||
{
|
||||
SimpleGUI gui;
|
||||
gui.run();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
#include "Widgets.hpp"
|
||||
|
||||
namespace tp {
|
||||
|
||||
class SimpleWidget : public CollapsableMenu {
|
||||
public:
|
||||
SimpleWidget() {
|
||||
this->addWidgetToMenu(&mSlider);
|
||||
|
||||
this->addWidgetToMenu(&mInMenuButton1);
|
||||
this->addWidgetToMenu(&mInMenuButton2);
|
||||
|
||||
this->addWidgetToMenu(&mLabel);
|
||||
|
||||
mInMenuButton1.mLabel.mLabel = "Button1";
|
||||
|
||||
mInMenuButton1.mCallback = []() {
|
||||
printf("asd\n");
|
||||
};
|
||||
|
||||
mInMenuButton2.mLabel.mLabel = "Button2";
|
||||
}
|
||||
|
||||
private:
|
||||
ButtonWidget mInMenuButton1;
|
||||
ButtonWidget mInMenuButton2;
|
||||
|
||||
LabelWidget mLabel;
|
||||
NamedSliderWidget mSlider;
|
||||
};
|
||||
|
||||
class SimpleWidget3 : public WorkspaceWidget {
|
||||
public:
|
||||
SimpleWidget3() {
|
||||
|
||||
mDockSpace.addSideWidget(&mButtons[0], DockWidget::BOTTOM);
|
||||
mDockSpace.addSideWidget(&mButtons[1], DockWidget::RIGHT);
|
||||
|
||||
mDockSpace.removeSideWidget(DockWidget::BOTTOM);
|
||||
|
||||
mDockSpace.addSideWidget(&mButtons[0], DockWidget::TOP);
|
||||
mDockSpace.addSideWidget(&mButtons[2], DockWidget::LEFT);
|
||||
|
||||
mDockSpace.removeSideWidget(DockWidget::TOP);
|
||||
|
||||
mDockSpace.addSideWidget(&mButtons[0], DockWidget::BOTTOM);
|
||||
|
||||
mDockSpace.addSideWidget(&mButtons[3], DockWidget::TOP);
|
||||
mDockSpace.setCenterWidget(&mButtons[4]);
|
||||
|
||||
/*
|
||||
mButtons[4].mCallback = [&]() { mDockSpace.toggleHiddenState(DockSpaceWidget::BOTTOM); };
|
||||
mButtons[0].mCallback = [&]() { mDockSpace.toggleHiddenState(DockSpaceWidget::TOP); };
|
||||
mButtons[2].mCallback = [&]() { mDockSpace.toggleHiddenState(DockSpaceWidget::RIGHT); };
|
||||
mButtons[3].mCallback = [&]() { mDockSpace.toggleHiddenState(DockSpaceWidget::LEFT); };
|
||||
*/
|
||||
|
||||
mButtons[0].addWidgetToMenu(&mWidget);
|
||||
mButtons[1].addWidgetToMenu(&mWidget2);
|
||||
}
|
||||
|
||||
private:
|
||||
FloatingWidget mButtons[5];
|
||||
|
||||
SimpleWidget mWidget;
|
||||
SimpleWidget mWidget2;
|
||||
SimpleWidget mWidget3;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue