[zhoulongyu] simpleness open the emulator window

This commit is contained in:
zhoulongyu 2024-08-05 01:37:50 +08:00
parent fd9395dd89
commit c5436c077f
25 changed files with 955 additions and 178 deletions

View File

@ -86,4 +86,8 @@ set(APPLICATION_VERSION_1 1)
set(APPLICATION_VERSION_2 0)
set(APPLICATION_VERSION_3 0)
set(APPLICATION_VERSION_4 0)
# ------------ build upgrade end ------------ #
# ------------ build upgrade end ------------ #
# ------------ build Gui ------------ #
set(GUI_IMAGES_PATH "./gui_engine")
# ------------ build Gui end ------------ #

View File

@ -27,4 +27,5 @@ add_subdirectory(ffmpeg)
add_subdirectory(fdk-aac)
# ================= ffmpeg related end ================= #
add_subdirectory(libconfig)
# add_subdirectory(libfaac)
# add_subdirectory(libfaac)
add_subdirectory(lvgl_simulator)

@ -0,0 +1 @@
Subproject commit 8c5e36b4ec2ceef99ca4c26dd657bd03f9922630

View File

@ -7,14 +7,14 @@
#include <unistd.h>
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
#include <SDL2/SDL.h>
#include "lvgl/lvgl.h"
#include "../lvgl_simulator/lvgl/lvgl.h"
#include "lvgl_main.h"
#include "lvgl/examples/lv_examples.h"
#include "../lvgl_simulator/lvgl/examples/lv_examples.h"
// #include "lv_examples/lv_demo.h"
#include "lv_drivers/display/monitor.h"
#include "lv_drivers/indev/mouse.h"
#include "lv_drivers/indev/keyboard.h"
#include "lv_drivers/indev/mousewheel.h"
#include "../lvgl_simulator/lv_drivers/display/monitor.h"
#include "../lvgl_simulator/lv_drivers/indev/mouse.h"
#include "../lvgl_simulator/lv_drivers/indev/keyboard.h"
#include "../lvgl_simulator/lv_drivers/indev/mousewheel.h"
/*********************
* DEFINES

View File

@ -6,7 +6,7 @@
/*********************
* INCLUDES
*********************/
#include "monitor.h"
#include "../lvgl_simulator/lv_drivers/display/monitor.h"
#if USE_MONITOR
#ifndef MONITOR_SDL_INCLUDE_PATH
@ -17,9 +17,9 @@
#include <stdbool.h>
#include <string.h>
#include MONITOR_SDL_INCLUDE_PATH
#include "../indev/mouse.h"
#include "../indev/keyboard.h"
#include "../indev/mousewheel.h"
#include "../lvgl_simulator/lv_drivers/indev/mouse.h"
#include "../lvgl_simulator/lv_drivers/indev/keyboard.h"
#include "../lvgl_simulator/lv_drivers/indev/mousewheel.h"
/*********************
* DEFINES

View File

@ -7,4 +7,5 @@ add_subdirectory(MediaManager)
add_subdirectory(AppManager)
add_subdirectory(StorageManager)
add_subdirectory(FilesManager)
add_subdirectory(HuntingUpgrade)
add_subdirectory(HuntingUpgrade)
add_subdirectory(GuiEngine)

View File

@ -1,11 +1,15 @@
include(${CMAKE_SOURCE_DIR_SIFARSDK}/build/global_config.cmake)
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})
set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})
include_directories(
./src
./include
${COMPONENT_SOURCE_PATH}/Log/include
./InterfaceEntryManage
${UTILS_SOURCE_PATH}/StatusCode/include
${UTILS_SOURCE_PATH}/Log/include
${COMPONENT_SOURCE_PATH}/ReturnCode/include
# ${COMPONENT_SOURCE_PATH}/Log/include
)
#Rely on other library
@ -29,19 +33,35 @@ file(GLOB_RECURSE ABSTRACT_FILE abstract/*.cpp abstract/*.c)
set(ABSTRACT_TARGET_NAME GuiEngineAbstract)
add_library(${ABSTRACT_TARGET_NAME} STATIC ${ABSTRACT_FILE})
if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX})
# build the lvgl sumlator in linux.
include_directories(
./lvgl_common
${EXTERNAL_SOURCE_PATH}/lvglLinux-x86/lv_sim_vscode_sdl/lvgl
${EXTERNAL_SOURCE_PATH}/lvgl_simulator/lvgl_simulator/lvgl
# ${EXTERNAL_SOURCE_PATH}/lvglLinux-x86/lv_sim_vscode_sdl/lvgl
)
aux_source_directory(./lvgl_x86 SRC_FILES)
aux_source_directory(./lvgl_x86/screen_240x320/images SRC_FILES)
aux_source_directory(./lvgl_common SRC_FILES)
set(TARGET_NAME GuiEngine-lvglx86)
add_library(${TARGET_NAME} STATIC ${SRC_FILES})
target_link_libraries(${TARGET_NAME} lvgl-x86 ReturnCode Log)
aux_source_directory(./InterfaceEntryManage SRC_FILES)
# set(TARGET_NAME GuiEngine-lvglx86)
# add_library(${TARGET_NAME} STATIC ${SRC_FILES})
# target_link_libraries(${TARGET_NAME} GuiEngineAbstract lvgl-x86 ReturnCode Log)
file(GLOB_RECURSE LVGL_SRC_FILES ${EXTERNAL_SOURCE_PATH}/lvgl_simulator/lvgl_simulator/lvgl/src/*.c)
# file(GLOB_RECURSE LVGL_DRIVERS_SRC_FILES ${EXTERNAL_SOURCE_PATH}/lvgl_simulator/lvgl_simulator/lv_drivers/*.c)
set(TARGET_NAME GuiEngine-x86)
add_library(${TARGET_NAME} STATIC ${SRC_FILES} ${LVGL_SRC_FILES} ${LVGL_DRIVERS_SRC_FILES})
target_link_libraries(${TARGET_NAME} GuiEngineAbstract lvglSimulator StatusCode Log)
# target_link_libraries(${TARGET_NAME} GuiEngineAbstract lvglSimulator ReturnCode Log)
else()
include_directories(
./lvgl_common
${EXTERNAL_SOURCE_PATH}/lvglBoard
@ -58,5 +78,9 @@ else()
target_link_libraries(${TARGET_NAME} GuiEngineAbstract ReturnCode Log)
endif()
define_file_basename_for_sources(${TARGET_NAME})
define_file_basename_for_sources(${ABSTRACT_TARGET_NAME})
define_file_name(${TARGET_NAME})
define_file_name(${ABSTRACT_TARGET_NAME})
# define_file_basename_for_sources(${TARGET_NAME})
# define_file_basename_for_sources(${ABSTRACT_TARGET_NAME})

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, softwareZhoufuwuqimima123
*
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "InterfaceEntryManage.h"
#include "ILog.h"
#include <algorithm>
StatusCode InterfaceEntry::InterfaceEntryFuncArray_pusBack(InterfaceEntryFunc func)
{
if (std::find(InterfaceEntryFuncArray.begin(), InterfaceEntryFuncArray.end(), func) != InterfaceEntryFuncArray.end())
{
LogInfo("func already exist\n");
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
InterfaceEntryFuncArray.push_back(func);
return CreateStatusCode(STATUS_CODE_OK);
}
void InterfaceEntryFuncArrayOperation(void)
{
std::vector<InterfaceEntryFunc> interfaceFuncArray = InterfaceEntry::GetInstance()->InterfaceEntryFuncArray;
int size = interfaceFuncArray.size();
for(int i = 0; i<size; i++)
{
interfaceFuncArray[i]();
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INTERFACEENTRYMANAGE_H
#define INTERFACEENTRYMANAGE_H
#include "GuiEngine.h"
#include <vector>
typedef void (*InterfaceEntryFunc)(void);
class InterfaceEntry
{
public:
// InterfaceEntry();
// virtual ~InterfaceEntry() = default;
static std::shared_ptr<InterfaceEntry> &GetInstance(std::shared_ptr<InterfaceEntry> *impl = nullptr)
{
static auto instance = std::make_shared<InterfaceEntry>();
if (impl)
{
/**
* @brief
* The non-thread-safe changing is only for gtest.
*/
instance = *impl;
}
return instance;
}
StatusCode InterfaceEntryFuncArray_pusBack(InterfaceEntryFunc func);
public:
std::vector<InterfaceEntryFunc> InterfaceEntryFuncArray;
};
void InterfaceEntryFuncArrayOperation(void);
#endif /* INTERFACEENTRYMANAGE_H */

View File

@ -1,75 +1,87 @@
/*
* @Descripttion: Api of gui in open source.
* @Date: 2022-08-02 16:02:16
* @LastEditTime: 2022-08-09 15:21:07
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, softwareZhoufuwuqimima123
*
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GUI_ENGINE_H
#define GUI_ENGINE_H
#include "ReturnCode.h"
#include "StatusCode.h"
#include <memory>
#define TR_TEXT(text) GuiEngine::GetInstance()->GetTranslateText(text)
#if 0
#define GUI_SET_IMAGE_FILE_SYSTEM_SRC(widget, src) widget->ImageSetSrc(&src); // use image src pointer.
#else
// #define GUI_SET_IMAGE_FILE_SYSTEM_SRC(widget, src) widget->ImageSetSrc("A:./"#src); // use image file.
#define GUI_SET_IMAGE_FILE_SYSTEM_SRC(widget, src) widget->ImageSetSrc(GUI_IMAGES_PATH#src); // use image file.
#endif
enum class i_lv_event_code_t{
I_LV_EVENT_ALL = 0,
I_LV_EVENT_CLICKED, /**< Called on release if not scrolled (regardless to long press)*/
};
enum class i_lv_align_t{
I_LV_ALIGN_DEFAULT = 0,
I_LV_ALIGN_TOP_LEFT,
I_LV_ALIGN_TOP_MID,
I_LV_ALIGN_TOP_RIGHT,
I_LV_ALIGN_BOTTOM_LEFT,
I_LV_ALIGN_BOTTOM_MID,
I_LV_ALIGN_BOTTOM_RIGHT,
I_LV_ALIGN_LEFT_MID,
I_LV_ALIGN_RIGHT_MID,
I_LV_ALIGN_CENTER,
I_LV_ALIGN_OUT_TOP_LEFT,
I_LV_ALIGN_OUT_TOP_MID,
I_LV_ALIGN_OUT_TOP_RIGHT,
I_LV_ALIGN_OUT_BOTTOM_LEFT,
I_LV_ALIGN_OUT_BOTTOM_MID,
I_LV_ALIGN_OUT_BOTTOM_RIGHT,
I_LV_ALIGN_OUT_LEFT_TOP,
I_LV_ALIGN_OUT_LEFT_MID,
I_LV_ALIGN_OUT_LEFT_BOTTOM,
I_LV_ALIGN_OUT_RIGHT_TOP,
I_LV_ALIGN_OUT_RIGHT_MID,
I_LV_ALIGN_OUT_RIGHT_BOTTOM,
};
typedef void (*i_lv_event_cb_t)(i_lv_event_code_t e, void * userData);
class Widget
{
public:
Widget() = default;
virtual ~Widget() {}
// virtual bool IsValid() { return false; }
// virtual std::string Name() { return "null"; }
// virtual void SetWidget(Widget *p) {}
// virtual int GetCoordX() { return 0; }
// virtual int GetCoordY() { return 0; }
virtual std::shared_ptr<Widget> NewImage(void) { return std::make_shared<Widget>(); }
virtual std::shared_ptr<Widget> NewLabel(void) { return std::make_shared<Widget>(); }
virtual void ImageSetSrc(const void *src) {}
virtual void SetSize(const unsigned int &width, const unsigned int &height) {}
virtual void SetSize(const int16_t width, const int16_t height) {}
virtual void SetColor(uint32_t color) {}
virtual void Load(void) {}
virtual void SetText(const char *text) {}
virtual void AlignTo(std::shared_ptr<Widget> base, i_lv_align_t align, int16_t posX, int16_t posY) {}
virtual void SetPos(int16_t posX, int16_t posY) {}
virtual void Center(void) {}
virtual void SetEventCb(i_lv_event_cb_t eventCb) {}
virtual void EventSend(i_lv_event_code_t e, void * userData) {}
// lv_res_t lv_event_send(lv_obj_t * obj, lv_event_code_t event_code, void * param)
virtual void Delete(void) {}
};
class Context
{
public:
Context()
{
eventCallback = nullptr;
ctx = nullptr;
// cmd = KeyCmd::KEY_CMD_DEFAULT;
}
std::unique_ptr<Widget> widget;
void (*eventCallback)(std::shared_ptr<Context> &ctx);
bool (*timerCallback)(void *);
// KeyCmd cmd;
void *ctx;
public:
virtual ~Context()
{
}
virtual int Type() { return 0; }
void WidgetReset(Widget *p)
{
widget.reset(p);
}
/**
* @brief Set transparency
* @param opaValue 0~255
* 0: transparency
* 255:opacification
* 10%= 25; 20%= 51; 30%= 76; 40%= 102; 50%= 127; 60%= 153; 70%= 178; 80%= 204; 90%= 229; 100%= 255;
*/
virtual void SetOpa(const uint8_t opaValue = 0) {}
};
template <typename T>
class ContextV2 : public Context
{
public:
T data;
public:
ContextV2(T value)
: data(value)
{
}
virtual ~ContextV2() = default;
};
class GuiEngine
{
public:
@ -104,15 +116,22 @@ public:
* @param height height of screen
* @param appInit for app to init the first window
*/
virtual bool Init(const unsigned int &width, const unsigned int &height, void (*appInit)()) { return false; }
virtual bool Init(const unsigned int width, const unsigned int height, void (*appInit)()) { return false; }
virtual void UnInit() {}
virtual const char *GetTranslateText(const char *trText) { return "nullptr"; }
virtual const int16_t GetScreenWidth(void) { return 1;}
virtual const int16_t GetScreenHeight(void) { return 1;}
virtual StatusCode CreateFrameParObject(int16_t widht = 100, int16_t height = 100, int16_t posX = 0, int16_t posY = 0) { return CreateStatusCode(STATUS_CODE_OK); } // 这个界面不应该放出来, 在应用层初始化的时候使用
virtual std::shared_ptr<Widget> GetFrameParObject(void) { return std::make_shared<Widget>(); }
virtual StatusCode SetNowNode(std::shared_ptr<Widget>) { return CreateStatusCode(STATUS_CODE_OK); } // 这个函数不应该放出来, 在切换界面的时候使用
virtual std::shared_ptr<Widget> GetNowNode(void) { return nullptr; }
virtual std::shared_ptr<Widget> NewWidget(void) { return std::make_shared<Widget>(); }
virtual std::shared_ptr<Widget> NewPage(void) { return std::make_shared<Widget>(); }
virtual std::shared_ptr<Widget> NewImage(const std::shared_ptr<Widget> &parent) { return std::make_shared<Widget>(); }
// virtual std::shared_ptr<Widget> PageOpen(const std::string &windowName) { return std::make_shared<Widget>(); }
// virtual SF_CODE_S PageColse(const std::shared_ptr<Widget> &page) { return CreateReturnCode(SF_CODE_OK); }
virtual void IdleQueue(const std::shared_ptr<Context> &ctx) {}
virtual std::shared_ptr<Widget> NewImage(void) { return std::make_shared<Widget>(); }
virtual std::shared_ptr<Widget> NewButton(void) { return std::make_shared<Widget>(); }
};
bool CreateGuiEngineImpl();
#endif
#endif

View File

@ -8,7 +8,7 @@ bool CreateGuiEngineImpl()
GuiEngine::GetInstance(&impl);
return true;
}
bool LvglLinuxBoard::Init(const unsigned int &width, const unsigned int &height, void (*appInit)())
bool LvglLinuxBoard::Init(const unsigned int width, const unsigned int height, void (*appInit)())
{
auto mainFunc = [](const unsigned int width_, const unsigned int height_, void (*appInit_)())
{
@ -21,4 +21,4 @@ void LvglLinuxBoard::UnInit()
{
lvgl_board_exit();
std::cout << "LvglLinuxBoard UnInit." << std::endl;
}
}

View File

@ -7,7 +7,7 @@ class LvglLinuxBoard : public GuiLvgl
public:
LvglLinuxBoard() = default;
virtual ~LvglLinuxBoard() = default;
bool Init(const unsigned int &width, const unsigned int &height, void (*appInit)()) override;
bool Init(const unsigned int width, const unsigned int height, void (*appInit)()) override;
void UnInit() override;
};
#endif
#endif

View File

@ -2,7 +2,7 @@
#include "demos/lv_demos.h"
#include "display/fbdev.h"
#include "indev/evdev.h"
#include "Log.h"
#include "ILog.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>

View File

@ -1,44 +1,140 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, softwareZhoufuwuqimima123
*
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "GuiLvgl.h"
#include "lvgl.h"
#include "Log.h"
#include "ILog.h"
#include "LvglWidget.h"
static void idle_queue_timer_cb(lv_timer_t *timer)
{
IdleQueueTimer *idleTimer = (IdleQueueTimer *)(timer->user_data);
std::shared_ptr<Context> ctx = idleTimer->ctx;
if (ctx->eventCallback)
{
ctx->eventCallback(ctx);
}
lv_timer_del(idleTimer->mTimer);
idleTimer->mTimer = nullptr;
delete (idleTimer);
}
GuiLvgl::GuiLvgl()
{
}
void GuiLvgl::IdleQueue(const std::shared_ptr<Context> &ctx)
/**
* @brief Get screen width
*
* @return Screen width value
*/
const int16_t GuiLvgl::GetScreenWidth(void)
{
IdleQueueTimer *newTimer = new IdleQueueTimer;
newTimer->ctx = ctx;
constexpr int NOT_SLEEP = 0;
newTimer->mTimer = lv_timer_create(idle_queue_timer_cb, NOT_SLEEP, newTimer);
return lv_obj_get_width(std::dynamic_pointer_cast<LvglWidget>(_ParWidget)->mWidget);
}
std::shared_ptr<Widget> GuiLvgl::NewPage(void)
/**
* @brief Get screen height
*
* @return Screen height
*/
const int16_t GuiLvgl::GetScreenHeight(void)
{
std::shared_ptr<LvglWidget> window = std::make_shared<LvglWidget>();
// window->mWidget = lv_win_create(lv_scr_act(), headerHeight);
window->mWidget = lv_obj_create(nullptr);
// window->mWidget = lv_win_create(lv_obj_create(nullptr), headerHeight);
LogInfo("create window %p\n", window->mWidget);
return window;
return lv_obj_get_height(std::dynamic_pointer_cast<LvglWidget>(_ParWidget)->mWidget);
}
std::shared_ptr<Widget> GuiLvgl::NewImage(const std::shared_ptr<Widget> &parent)
void FrameParObjectCb(i_lv_event_code_t e, void *userData)
{
if(GuiEngine::GetInstance()->GetNowNode() != nullptr)
{
GuiEngine::GetInstance()->GetNowNode()->EventSend(e, userData);
}
else
{
}
}
StatusCode GuiLvgl::CreateFrameParObject(int16_t widht, int16_t height, int16_t posX, int16_t posY)
{
std::shared_ptr<LvglWidget> widget = std::make_shared<LvglWidget>();
if (parent)
{
widget->mWidget = lv_img_create(std::dynamic_pointer_cast<LvglWidget>(parent)->mWidget);
}
widget->mWidget = lv_obj_create(lv_scr_act());
widget->SetOpa(0);
widget->SetSize(widht, height);
widget->SetEventCb(FrameParObjectCb);
widget->SetPos(0, 0);
lv_refr_now(NULL);
_ParWidget = widget;
return CreateStatusCode(STATUS_CODE_OK);
}
std::shared_ptr<Widget> GuiLvgl::GetFrameParObject(void)
{
return std::static_pointer_cast<LvglWidget>(_ParWidget);
}
StatusCode GuiLvgl::SetNowNode(std::shared_ptr<Widget> widget)
{
_NowNode = widget;
return CreateStatusCode(STATUS_CODE_OK);
}
std::shared_ptr<Widget> GuiLvgl::GetNowNode(void)
{
return _NowNode;
}
std::shared_ptr<Widget> GuiLvgl::NewWidget(void)
{
std::shared_ptr<LvglWidget> widget = std::make_shared<LvglWidget>();
widget->mWidget = lv_obj_create(JudgeParent());
return widget;
}
}
std::shared_ptr<Widget> GuiLvgl::NewPage(void)
{
return nullptr;
}
std::shared_ptr<Widget> GuiLvgl::NewImage(void)
{
std::shared_ptr<LvglWidget> widget = std::make_shared<LvglWidget>();
widget->mWidget = lv_img_create(JudgeParent());
return widget;
}
std::shared_ptr<Widget> GuiLvgl::NewButton(void)
{
std::shared_ptr<LvglWidget> widget = std::make_shared<ButtonWidget>();
widget->mWidget = lv_btn_create(JudgeParent());
lv_obj_set_pos(widget->mWidget, 0, 0); /*Set its position*/
lv_obj_set_size(widget->mWidget, 10, 10); /*Set its size*/
lv_obj_add_event_cb(widget->mWidget, nullptr, LV_EVENT_ALL, nullptr); /*Assign a callback to the button*/
return widget;
}
lv_obj_t* GuiLvgl::JudgeParent(void)
{
if (_NowNode != nullptr)
{
return (std::dynamic_pointer_cast<LvglWidget>(_NowNode)->mWidget);
}
else if (_ParWidget != nullptr)
{
// If no parent object is specified at the application layer, the parent window object of the application layer is used
return (std::dynamic_pointer_cast<LvglWidget>(_ParWidget)->mWidget);
}
else
{
//If the application layer does not specify a parent object, and the application layer's parent window object does not exist, LVGL's frame window object is used
return (lv_scr_act());
}
}

View File

@ -1,28 +1,47 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, softwareZhoufuwuqimima123
*
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GUI_LVGL_H
#define GUI_LVGL_H
#include "GuiEngine.h"
#include "lvgl.h"
class IdleQueueTimer
{
public:
IdleQueueTimer()
{
mTimer = nullptr;
}
~IdleQueueTimer() = default;
lv_timer_t *mTimer;
std::shared_ptr<Context> ctx;
};
class GuiLvgl : public GuiEngine
{
public:
GuiLvgl();
virtual ~GuiLvgl() = default;
void IdleQueue(const std::shared_ptr<Context> &ctx) override;
const int16_t GetScreenWidth(void) override;
const int16_t GetScreenHeight(void) override;
StatusCode CreateFrameParObject(int16_t widht, int16_t height, int16_t posX, int16_t posY) override;
std::shared_ptr<Widget> GetFrameParObject(void) override;
StatusCode SetNowNode(std::shared_ptr<Widget>) override;
std::shared_ptr<Widget> GetNowNode(void) override;
std::shared_ptr<Widget> NewWidget(void) override;
std::shared_ptr<Widget> NewPage(void) override;
std::shared_ptr<Widget> NewImage(const std::shared_ptr<Widget> &parent) override;
std::shared_ptr<Widget> NewImage(void) override;
std::shared_ptr<Widget> NewButton(void) override;
private:
// lv_timer_t *mIdleQueueTimer;
lv_obj_t* JudgeParent(void);
private:
std::shared_ptr<Widget> _LvglParWidget = nullptr;
std::shared_ptr<Widget> _ParWidget = nullptr;
std::shared_ptr<Widget> _NowNode = nullptr;
};
#endif // !GUI_LVGL_H
#endif // !GUI_LVGL_H

View File

@ -1,53 +1,146 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, softwareZhoufuwuqimima123
*
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LvglWidget.h"
#include "Log.h"
#include "ILog.h"
#include "images_handle.h"
std::shared_ptr<Widget> LvglWidget::NewImage(void)
i_lv_event_code_t transitionEventCode_MidApp(lv_event_code_t code)
{
std::shared_ptr<LvglWidget> widget = std::make_shared<LvglWidget>();
if (mWidget)
switch (code)
{
widget->mWidget = lv_img_create(mWidget);
case LV_EVENT_CLICKED:
return i_lv_event_code_t::I_LV_EVENT_CLICKED;
default:
return i_lv_event_code_t::I_LV_EVENT_ALL;
}
return widget;
}
std::shared_ptr<Widget> LvglWidget::NewLabel(void)
lv_event_code_t transitionEventCode_AppMid(i_lv_event_code_t code)
{
std::shared_ptr<LvglWidget> widget = std::make_shared<LvglWidget>();
if (mWidget)
switch (code)
{
widget->mWidget = lv_label_create(mWidget);
case i_lv_event_code_t::I_LV_EVENT_CLICKED:
return LV_EVENT_CLICKED;
default:
return LV_EVENT_ALL;
}
return widget;
}
void LvglWidget::ImageSetSrc(const void *src)
lv_align_t transitionAlignCode_AppMid(i_lv_align_t align)
{
switch (align)
{
case i_lv_align_t::I_LV_ALIGN_DEFAULT:
return LV_ALIGN_DEFAULT;
case i_lv_align_t::I_LV_ALIGN_TOP_LEFT:
return LV_ALIGN_TOP_LEFT;
case i_lv_align_t::I_LV_ALIGN_TOP_MID:
return LV_ALIGN_TOP_MID;
case i_lv_align_t::I_LV_ALIGN_TOP_RIGHT:
return LV_ALIGN_TOP_RIGHT;
case i_lv_align_t::I_LV_ALIGN_BOTTOM_LEFT:
return LV_ALIGN_BOTTOM_LEFT;
case i_lv_align_t::I_LV_ALIGN_BOTTOM_MID:
return LV_ALIGN_BOTTOM_MID;
case i_lv_align_t::I_LV_ALIGN_BOTTOM_RIGHT:
return LV_ALIGN_BOTTOM_RIGHT;
case i_lv_align_t::I_LV_ALIGN_LEFT_MID:
return LV_ALIGN_LEFT_MID;
case i_lv_align_t::I_LV_ALIGN_RIGHT_MID:
return LV_ALIGN_RIGHT_MID;
case i_lv_align_t::I_LV_ALIGN_CENTER:
return LV_ALIGN_CENTER;
case i_lv_align_t::I_LV_ALIGN_OUT_TOP_LEFT:
return LV_ALIGN_OUT_TOP_LEFT;
case i_lv_align_t::I_LV_ALIGN_OUT_TOP_MID:
return LV_ALIGN_OUT_TOP_MID;
case i_lv_align_t::I_LV_ALIGN_OUT_TOP_RIGHT:
return LV_ALIGN_OUT_TOP_RIGHT;
case i_lv_align_t::I_LV_ALIGN_OUT_BOTTOM_LEFT:
return LV_ALIGN_OUT_BOTTOM_LEFT;
case i_lv_align_t::I_LV_ALIGN_OUT_BOTTOM_MID:
return LV_ALIGN_OUT_BOTTOM_MID;
case i_lv_align_t::I_LV_ALIGN_OUT_BOTTOM_RIGHT:
return LV_ALIGN_OUT_BOTTOM_RIGHT;
case i_lv_align_t::I_LV_ALIGN_OUT_LEFT_TOP:
return LV_ALIGN_OUT_LEFT_TOP;
case i_lv_align_t::I_LV_ALIGN_OUT_LEFT_MID:
return LV_ALIGN_OUT_LEFT_MID;
case i_lv_align_t::I_LV_ALIGN_OUT_LEFT_BOTTOM:
return LV_ALIGN_OUT_LEFT_BOTTOM;
case i_lv_align_t::I_LV_ALIGN_OUT_RIGHT_TOP:
return LV_ALIGN_OUT_RIGHT_TOP;
case i_lv_align_t::I_LV_ALIGN_OUT_RIGHT_MID:
return LV_ALIGN_OUT_RIGHT_MID;
case i_lv_align_t::I_LV_ALIGN_OUT_RIGHT_BOTTOM:
return LV_ALIGN_OUT_RIGHT_BOTTOM;
default:
return LV_ALIGN_CENTER;
}
}
void LvglWidget::AlignTo(std::shared_ptr<Widget> base, i_lv_align_t align, int16_t posX, int16_t posY)
{
if (mWidget)
{
LogInfo("================================= image src = %s\n", (char *)src);
lv_img_set_src(mWidget, src);
if(base == nullptr)
{
lv_obj_align_to(mWidget, nullptr, transitionAlignCode_AppMid(align), posX, posY);
}
else
{
std::shared_ptr<LvglWidget> _base = std::dynamic_pointer_cast<LvglWidget>(base);
lv_obj_align_to(mWidget, _base->mWidget, transitionAlignCode_AppMid(align), posX, posY);
}
}
}
void LvglWidget::SetSize(const unsigned int &width, const unsigned int &height)
void LvglWidget::SetPos(int16_t posX, int16_t posY)
{
if (mWidget)
{
lv_obj_set_size(mWidget, width, height);
lv_obj_set_pos(mWidget, posX, posY);
}
}
void LvglWidget::Load(void)
/**
* @brief aligns the object to the center of its parent object.
*
* Note that if the size of the parent element changes, 'obj' needs to be manually aligned again
*/
void LvglWidget::Center(void)
{
if (mWidget)
{
lv_scr_load(mWidget);
}
}
void LvglWidget::SetText(const char *text)
{
if (mWidget)
{
lv_label_set_text(mWidget, text);
lv_obj_center(mWidget);
}
}
/**
* @brief deletes the LvglWidget object
*
* Deletes the current LvglWidget object and frees the associated resources.
*/
void LvglWidget::Delete(void)
{
if (mWidget)
@ -55,4 +148,96 @@ void LvglWidget::Delete(void)
lv_obj_del(mWidget);
mWidget = nullptr;
}
}
}
void LvglWidget::SetOpa(const uint8_t opaValue)
{
if (mWidget)
{
lv_obj_set_style_bg_opa(mWidget, opaValue, 0);
}
}
void LvglWidget::SetSize(const int16_t width, const int16_t height)
{
if (mWidget)
{
lv_obj_set_size(mWidget, width, height);
}
}
void LvglWidget::SetColor(uint32_t color)
{
if (mWidget)
{
lv_obj_set_style_bg_color(mWidget, lv_color_hex(color), 0);
}
}
static void publicEventCb(lv_event_t * e)
{
LvglWidget * kb = (LvglWidget *)lv_event_get_user_data(e);
lv_event_code_t code = lv_event_get_code(e);
kb->mEventCb(transitionEventCode_MidApp(code), nullptr); // 这里的 nullptr 需要改, 不是这样的,而是根据具体的需求
}
void LvglWidget::SetEventCb(i_lv_event_cb_t eventCb)
{
if (mWidget)
{
mEventCb = eventCb;
lv_obj_add_event_cb(mWidget, publicEventCb, LV_EVENT_ALL, this);
}
}
void LvglWidget::EventSend(i_lv_event_code_t e, void * userData)
{
if (mWidget)
{
lv_event_send(mWidget, transitionEventCode_AppMid(e), nullptr);
}
}
void ImageWidget::ImageSetSrc(const void *src)
{
if (mWidget)
{
// LogInfo("================================= image src = %s\n", (char *)src);
lv_img_set_src(mWidget, src);
}
}
/**
* @brief sets the label text
*
* @param text Indicates the text content
*/
void LabelWidget::SetText(const char *text)
{
if (mWidget)
{
lv_label_set_text(mWidget, text);
}
}
/**
* @brief Sets the color of the button control
*
* @param color Color value
*/
void ButtonWidget::SetColor(uint32_t color)
{
if (mWidget)
{
// 打桩
}
}

View File

@ -1,7 +1,25 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, softwareZhoufuwuqimima123
*
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LVGL_WIDGET_H
#define LVGL_WIDGET_H
#include "GuiEngine.h"
#include "lvgl.h"
class LvglWidget : public Widget
{
public:
@ -10,15 +28,43 @@ public:
mWidget = nullptr;
}
virtual ~LvglWidget() = default;
std::shared_ptr<Widget> NewImage(void) override;
std::shared_ptr<Widget> NewLabel(void) override;
void ImageSetSrc(const void *src) override;
void SetSize(const unsigned int &width, const unsigned int &height) override;
void Load(void) override;
void SetText(const char *text) override;
void SetSize(const int16_t width, const int16_t height) override;
// void Load(void) override; // 好像挺有用的, 但不知道什么意思
void Center(void) override;
void SetColor(uint32_t color) override;
void AlignTo(std::shared_ptr<Widget> base, i_lv_align_t align, int16_t posX, int16_t posY) override;
void SetPos(int16_t posX, int16_t posY) override;
void SetOpa(const uint8_t opaValue) override;
void SetEventCb(i_lv_event_cb_t eventCb) override;
void EventSend(i_lv_event_code_t e, void * userData) override;
void Delete(void) override;
public:
lv_obj_t *mWidget;
i_lv_event_cb_t mEventCb;
};
#endif // !LVGL_WIDGET_H
class ImageWidget : public LvglWidget
{
public:
void ImageSetSrc(const void *src) override;
};
class ButtonWidget : public LvglWidget
{
public:
void SetColor(uint32_t color) override;
};
class LabelWidget : public LvglWidget
{
public:
void SetText(const char *text) override;
};
#endif // !LVGL_WIDGET_H

View File

@ -1,5 +1,6 @@
#include "InterfaceEntryManage.h"
#include "LvglLinux_x86.h"
#include "Log.h"
#include "ILog.h"
#include <iostream>
#include <thread>
#ifdef __cplusplus
@ -19,13 +20,10 @@ bool CreateGuiEngineImpl()
GuiEngine::GetInstance(&impl);
return true;
}
bool LvglLinuxX86::Init(const unsigned int &width, const unsigned int &height, void (*appInit)())
bool LvglLinuxX86::Init(const unsigned int width, const unsigned int height, void (*appInit)())
{
auto mainFunc = [](const unsigned int width_, const unsigned int height_, void (*appInit_)())
{
mainTest(width_, height_, appInit_);
};
std::thread(mainFunc, width, height, appInit).detach();
InterfaceEntry::GetInstance()->InterfaceEntryFuncArray_pusBack(appInit);
mainTest(width, height, InterfaceEntryFuncArrayOperation);
return true;
}
void LvglLinuxX86::UnInit()
@ -38,4 +36,4 @@ void LvglLinuxX86::UnInit()
std::this_thread::sleep_for(std::chrono::milliseconds(1000 * 2));
// monitor_uninit();
std::cout << "LvglLinuxX86 UnInit." << std::endl;
}
}

View File

@ -7,7 +7,7 @@ class LvglLinuxX86 : public GuiLvgl
public:
LvglLinuxX86() = default;
virtual ~LvglLinuxX86() = default;
bool Init(const unsigned int &width, const unsigned int &height, void (*appInit)()) override;
bool Init(const unsigned int width, const unsigned int height, void (*appInit)()) override;
void UnInit() override;
};
#endif
#endif

View File

@ -41,5 +41,6 @@ add_subdirectory(all)
add_subdirectory(application)
add_subdirectory(middleware)
add_subdirectory(utils)
add_subdirectory(GuiInterface)
add_subdirectory(hal)

View File

@ -0,0 +1,70 @@
# include(${CMAKE_SOURCE_DIR}/build/independent_source.cmake)
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}/bin)
include_directories(
.
./src
${UTILS_SOURCE_PATH}/Log/include
${UTILS_SOURCE_PATH}/StatusCode/include
${MIDDLEWARE_SOURCE_PATH}/GuiEngine/include
${MIDDLEWARE_SOURCE_PATH}/GuiEngine/InterfaceEntryManage
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include
)
link_directories(
${LIBS_OUTPUT_PATH}
${EXTERNAL_LIBS_OUTPUT_PATH}
)
aux_source_directory(. SRC_FILES_MAIN)
aux_source_directory(./src SRC_FILES)
set(TARGET_NAME GuiInterfaceTest)
add_executable(${TARGET_NAME} ${SRC_FILES_MAIN} ${SRC_FILES})
target_link_libraries(${TARGET_NAME} GuiEngine-x86 Log gtest gmock pthread)
if(${TEST_COVERAGE} MATCHES "true")
target_link_libraries(${TARGET_NAME} gcov)
endif()
if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")
add_custom_target(
GuiInterfaceTest_code_check
COMMAND ${CLANG_TIDY_EXE}
-checks='${CLANG_TIDY_CHECKS}'
--header-filter=.*
--system-headers=false
${SRC_FILES}
${CLANG_TIDY_CONFIG}
# --line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/gtest.h\"}]'
--line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/*.h\"}]'
-p ${PLATFORM_PATH}/cmake-shell
WORKING_DIRECTORY ${TEST_SOURCE_PATH}/GuiInterface
)
add_custom_command(
TARGET ${TARGET_NAME}
PRE_BUILD
COMMAND make GuiInterfaceTest_code_check
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
)
file(GLOB_RECURSE HEADER_FILES *.h)
add_custom_target(
GuiInterfaceTest_code_format
COMMAND ${CLANG_FORMAT_EXE}
-style=file
-i ${SRC_FILES} ${SRC_FILES_MAIN} ${HEADER_FILES}
WORKING_DIRECTORY ${TEST_SOURCE_PATH}/GuiInterface
)
add_custom_command(
TARGET ${TARGET_NAME}
PRE_BUILD
COMMAND make GuiInterfaceTest_code_check
COMMAND make GuiInterfaceTest_code_format
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
)
endif()
define_file_name(${TARGET_NAME})

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <thread>
#include <unistd.h>
int main(int argc, char *argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, softwareZhoufuwuqimima123
*
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "GuiEngine.h"
#include "GuiInterfaceTest.h"
#include "ILog.h"
#include "InterfaceEntryManage.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <thread>
namespace GuiInterfaceTest
{
class GuiInterfaceTest : public testing::Test /*, public DeviceManagerTestTool*/
{
public:
GuiInterfaceTest()
{
}
virtual ~GuiInterfaceTest()
{
}
static void SetUpTestCase()
{
CreateLogModule();
ILogInit(LOG_INSTANCE_TYPE_END);
}
static void TearDownTestCase()
{
ILogUnInit();
}
virtual void SetUp()
{
CreateAllKeysMcok();
// HalTestTool::Init();
// DeviceManagerTestTool::Init();
// CreateHalCppModule();
// CreateDeviceManagerModule();
// CreateMcuManager();
}
virtual void TearDown()
{
// HalTestTool::UnInit();
// DeviceManagerTestTool::UnInit();
// DestroyDeviceManagerModule();
DestroyAllKeysMock();
}
private:
void CreateAllKeysMcok(void)
{
// std::shared_ptr<VKeyHal> key = HalTestTool::MakeKeyHalTest(KEY_TEST);
// mAllKeysMock[KEY_TEST] = key;
// std::shared_ptr<VLedHal> led = HalTestTool::MakeLedHalTest(LED_TEST);
// mAllLedsMock[LED_TEST] = led;
}
void DestroyAllKeysMock(void)
{
// mAllKeysMock.clear();
// mAllLedsMock.clear();
}
public:
// std::shared_ptr<LinuxTest> mLinuxTest;
};
// ../output_files/test/bin/GuiInterfaceTest --gtest_filter=GuiInterfaceTest.Demo
TEST_F(GuiInterfaceTest, Demo)
{
CreateGuiEngineImpl();
GuiEngine::GetInstance()->Init(LV_SCREEN_WIDTH, LV_SCREEN_HEIGHT, GuiTestMainWindow);
GuiTest::GetInstance()->GuiTestUninit();
GuiEngine::GetInstance()->UnInit();
}
}; // namespace GuiInterfaceTest

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, softwareZhoufuwuqimima123
*
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "GuiInterfaceTest.h"
#include "ILog.h"
std::shared_ptr<GuiTest> &GuiTest::GetInstance(std::shared_ptr<GuiTest> *impl)
{
static auto instance = std::make_shared<GuiTest>();
if (impl) {
if (instance.use_count() == 1) {
LogInfo("Instance changed succeed.\n");
instance = *impl;
}
else {
LogError("Can't changing the instance becase of using by some one.\n");
}
}
return instance;
}
void TestButtonCb(i_lv_event_code_t e, void *userData)
{
if (i_lv_event_code_t::I_LV_EVENT_CLICKED == e) {
LogInfo("Button Click");
}
}
const StatusCode GuiTest::GuiTestInit(const unsigned int width, const unsigned int height)
{
_guiTestPar = GuiEngine::GetInstance()->NewWidget();
_guiTestPar->SetSize(width, height);
_guiTestPar->SetColor(0x077290);
_guiTestPar->SetOpa(127);
_guiTestPar->AlignTo(NULL, i_lv_align_t::I_LV_ALIGN_RIGHT_MID, 0, 0);
_testButton = GuiEngine::GetInstance()->NewButton();
_testButton->SetSize(50, 50); /*Set its size*/
_testButton->SetEventCb(TestButtonCb);
_testButton->AlignTo(_guiTestPar, i_lv_align_t::I_LV_ALIGN_CENTER, 0, 0);
return CreateStatusCode(STATUS_CODE_OK);
}
const StatusCode GuiTest::GuiTestUninit(void)
{
return CreateStatusCode(STATUS_CODE_OK);
}
void GuiTestMainWindow(void)
{
// Create a parent window for the application layer
GuiEngine::GetInstance()->CreateFrameParObject(LV_SCREEN_WIDTH, LV_SCREEN_HEIGHT, 0, 0);
GuiTest::GetInstance()->GuiTestInit(LV_SCREEN_WIDTH, LV_SCREEN_HEIGHT);
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "GuiEngine.h"
#include "StatusCode.h"
#include <memory>
#define LV_SCREEN_WIDTH 320
#define LV_SCREEN_HEIGHT 380
class GuiTest
{
public:
const StatusCode GuiTestInit(const unsigned int width, const unsigned int height);
const StatusCode GuiTestUninit(void);
static std::shared_ptr<GuiTest> &GetInstance(std::shared_ptr<GuiTest> *impl = nullptr);
private:
std::shared_ptr<Widget> _guiTestPar;
std::shared_ptr<Widget> _testButton;
};
void GuiTestMainWindow(void);