코드 구조
이 섹션에서는 TouchGFX Designer에서 생성되는 코드에서부터 사용자가 작성하는 확장 코드에 이르기까지 TouchGFX 프로젝트의 구조에 대해 설명합니다.
생성 코드 vs 사용자 코드
TouchGFX Designer에서 생성되는 코드는 사용자가 작성하는 코드와 완전히 분리됩니다. 실제로 생성 코드는 generated/gui_generated
폴더에 있는 반면, 작성 코드는 gui
폴더에 있습니다.
gui_generated
코드는 사용자 코드 클래스를 위한 기본 클래스 역할을 합니다. 기본 클래스에는 TouchGFX Designer에서 구성된 모든 설정 코드를 포함하고 있습니다. 아래 클래스 다이어그램은 각 클래스의 관계를 나타낸 것입니다.
위 그림과 같이 TouchGFX Designer 애플리케이션은 3가지 코드 계층으로 구성됩니다.
- 엔진: 엔진 클래스는 TouchGFX에서 제공하는 표준 클래스로, 생성 클래스를 위한 기본 클래스 역할을 합니다.
- 생성: 생성 클래스와 해당하는 파일은 TouchGFX Designer에서 코드를 생성할 때마다 다시 생성됩니다. 코드 생성기가 다음 번에 실행될 때 사용자가 직접 변경했던 내용을 덮어쓰게 되기 때문에 이 클래스와 파일은 직접 편집하지 않아야 합니다. 이 클래스는 사용자 클래스를 위한 기본 클래스입니다.
- 사용자: 사용자 클래스란 사용자가 직접 작성하는 코드를 위한 것입니다. 사용자는 이 계층에서 원하는 코드를 자유롭게 입력할 수 있습니다. 사용자 클래스가 없는 경우 TouchGFX Designer에서 생성되지만 절대 변경되지는 않습니다. 이 클래스는 사용자의 소유이기 때문입니다.
Note
TouchGFX Designer에서 생성되는 파일
일반적으로 TouchGFX Designer는 TouchGFX 프로젝트에서 오직 generated
폴더에만 파일을 재생성합니다. 따라서 이 파일들은 덮어쓰이게 되므로 사용자가 직접 편집해서는 안 됩니다. 하지만 TouchGFX Designer는 컴파일에 필요하지만 누락된 파일을 생성하기도 하는데, 예를 들면 application.config
, simulator/main.cpp
, 그리고 assets/images/__designer
에 있는 스킨 이미지, assets/videos/__designer
에 있는 비디오 샘플 등이 있습니다. 실제로 TouchGFX Designer는 다음과 같은 요소만 있으면 프로젝트를 생성, 컴파일 및 실행할 수 있습니다.
- 프로젝트에 대해 설명하는
.touchgfx
파일 gui
폴더에 저장되는 사용자 코드(있는 경우)assets/images
폴더에 저장되는 사용자 이미지(있는 경우)assets/texts/texts.xml
파일에 포함되는 텍스트(있는 경우)assets/fonts
폴더에 저장되는 글꼴(있는 경우)assets/videos
폴더에 저장되는 비디오(있는 경우)
Tip
예시
아래에는 생성 코드와 사용자 코드를 모두 사용하는 애플리케이션에 관한 간단한 예시입니다. 이 예시를 통해 위에서 설명한 내용을 더욱 자세히 알아볼 수 있습니다.
TouchGFX Designer View
다음 예는 스크린이 하나뿐인 경우입니다. MyScreen
스크린은 Box box1
과 Button button1
으로 구성됩니다. 또한 button1
을 클릭했을 때 가상 함수 setRandomColor()
를 호출하는 상호작용을 설정했습니다.
버튼을 누를 때마다 배경 박스의 색상이 새로운 색상으로 무작위로 바뀌도록 만들어보겠습니다. 이러한 동작을 사용자 코드에 구현하여 사용자 정의 코드의 작성 방법을 시연하겠습니다.
계층
이 예에서 연관된 여러 클래스가 아래와 같이 보일 수 있습니다.
위 그림에서,
MyScreenViewBase
,FrontendApplicationBase
및FrontendHeapBase
가 생성 계층에 있는데, 이는 다음을 의미합니다.- TouchGFX Designer에서 변경 사항이 생길 때마다 이 기본 클래스들이 다시 생성됩니다.
- 사용자가 이 클래스를 직접 편집해서는 안 됩니다.
MyScreenView
,MyScreenPresenter
,FrontendApplication
및FrontendHeap
이 사용자 코드 공간에 생성되는데, 이는 다음을 의미합니다.- 이 코드들은 TouchGFX Designer에서 변경 사항이 생기더라도 다시 생성되지 않습니다.
- 사용자는 여기서 사용자 정의 코드를 자유롭게 추가할 수 있습니다.
box1
및button1
설정은 모두 생성된 view 기반 클래스인MyScreenViewBase
에서 이루어집니다.- 스크린 전환 시 호출되는 모든 함수는 생성된 애플리케이션 기반 클래스인
FrontendApplicationBase
에 위치합니다. - 적정량의 메모리가 할당되도록 하는 모든 기록은 생성된 힙 기반 클래스인
FrontendHeapBase
에 위치합니다.
사용자는 사용자 코드 클래스를 자유롭게 편집할 수 있습니다. 예를 들어 위젯을 더 추가할 수 있습니다. 여기서는 setRandomColor
함수만 실행하여 box1
의 색상의 변경해보겠습니다.
코드
view 기반 코드를 보면 TouchGFX Designer에서 생성되는 박스와 버튼에 대한 설정이 있습니다. 또한 buttonCallbackHandler
에 setRandomColor
가상 함수에 대한 설정과 호출도 있지만 여기서는 이 함수가 아무런 기능도 하지 않습니다.
MyApplication/generated/gui_generated/src/my_screen/MyScreenViewBase.cpp
/*********************************************************************************/
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
/*********************************************************************************/
#include <gui_generated/myscreen_screen/MyScreenViewBase.hpp>
#include <touchgfx/Color.hpp>
#include "BitmapDatabase.hpp"
MyScreenViewBase::MyScreenViewBase() :
buttonCallback(this, &MyScreenViewBase::buttonCallbackHandler)
{
box1.setPosition(0, 0, 800, 480);
box1.setColor(touchgfx::Color::getColorFromRGB(255, 255, 255));
button1.setXY(155, 106);
button1.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_ID), touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_PRESSED_ID));
button1.setAction(buttonCallback);
add(box1);
add(button1);
}
void MyScreenViewBase::setupScreen()
{
}
void MyScreenViewBase::buttonCallbackHandler(const touchgfx::AbstractButton& src)
{
if (&src == &button1)
{
//Interaction1
//When button1 clicked call virtual function
//Call setRandomColor
setRandomColor();
}
}
view 기반 클래스에서 헤더 파일을 보면 setRandomColor
선언과 더불어, 사용자 코드에서 함수를 재정의하고 실행하는 방법이 나와 있습니다.
MyApplication/generated/gui_generated/src/my_screen/MyScreenViewBase.hpp
/*********************************************************************************/
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
/*********************************************************************************/
#ifndef MYSCREENVIEWBASE_HPP
#define MYSCREENVIEWBASE_HPP
#include <gui/common/FrontendApplication.hpp>
#include <mvp/View.hpp>
#include <gui/myscreen_screen/MyScreenPresenter.hpp>
#include <touchgfx/widgets/Box.hpp>
#include <touchgfx/widgets/Button.hpp>
class MyScreenViewBase : public touchgfx::View<MyScreenPresenter>
{
public:
MyScreenViewBase();
virtual ~MyScreenViewBase() {}
virtual void setupScreen();
/*
* Virtual Action Handlers
*/
virtual void setRandomColor()
{
// Override and implement this function in MyScreen
}
protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}
/*
* Member Declarations
*/
touchgfx::Box box1;
touchgfx::Button button1;
private:
/*
* Callback Declarations
*/
touchgfx::Callback<MyScreenViewBase, const touchgfx::AbstractButton&> buttonCallback;
/*
* Callback Handler Declarations
*/
void buttonCallbackHandler(const touchgfx::AbstractButton& src);
};
#endif // MYSCREENVIEWBASE_HPP
이제 직접 실행해보겠습니다. 사용자 코드 헤더 파일인 MyScreenView.hpp
로 이동하여 함수를 재정의합니다.
MyApplication/generated/gui_generated/src/my_screen/MyScreenView.hpp
#ifndef MYSCREENVIEW_HPP
#define MYSCREENVIEW_HPP
#include <gui_generated/myscreen_screen/MyScreenViewBase.hpp>
#include <gui/myscreen_screen/MyScreenPresenter.hpp>
class MyScreenView : public MyScreenViewBase
{
public:
MyScreenView();
virtual ~MyScreenView() {}
virtual void setupScreen();
virtual void tearDownScreen();
virtual void setRandomColor();
protected:
};
#endif // MYSCREENVIEW_HPP
이제 MyScreenView
cpp 파일에서 setRandomColor
의 실제 동작을 구현해야 합니다.
MyApplication/gui/src/my_screen/MyScreenView.cpp
#include <gui/myscreen_screen/MyScreenView.hpp>
#include <touchgfx/Color.hpp>
#include <stdlib.h>
MyScreenView::MyScreenView()
{
}
void MyScreenView::setupScreen()
{
MyScreenViewBase::setupScreen();
}
void MyScreenView::tearDownScreen()
{
MyScreenViewBase::tearDownScreen();
}
void MyScreenView::setRandomColor()
{
box1.setColor(touchgfx::Color::getColorFromRGB(rand()&0xff, rand()&0xff, rand()&0xff));
box1.invalidate();
}
이제 시뮬레이터를 실행해 보면 버튼을 클릭할 때마다 배경 박스의 색상이 무작위로 바뀌면서 생성 코드와 사용자 코드를 이용해 간단한 애플리케이션을 생성하는 데 성공한 것을 알 수 있습니다.
Tip
또한 여러 가지를 혼합해서 조화롭게 생성하는 것도 가능합니다. 예를 들어 TouchGFX Designer 프로젝트에서 정의하지 않는 스크린도 넣을 수 있습니다. 그 밖에
gotoXYZ
함수를 FrontendApplication
클래스에 추가하거나 사용자 스크린에 필요한 view, presenter 그리고 전환을 FrontendHeap 에 추가할 수 있습니다
.