주요 내용으로 건너뛰기

코드 구조

이 섹션에서는 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 Designer에서 생성되는 코드는 사용자가 TouchGFX 애플리케이션을 설계하는 방식을 제한할 수 없도록 구성됩니다.

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
Git와 같은 버전 관리 시스템을 사용할 때도 실제로 위에 열거한 파일만 저장소로 커밋하면 됩니다. 나머지는 TouchGFX Designer 자체에서 생성되기 때문입니다.

예시

아래에는 생성 코드와 사용자 코드를 모두 사용하는 애플리케이션에 관한 간단한 예시입니다. 이 예시를 통해 위에서 설명한 내용을 더욱 자세히 알아볼 수 있습니다.

TouchGFX Designer View

다음 예는 스크린이 하나뿐인 경우입니다. MyScreen 스크린은 Box box1Button button1으로 구성됩니다. 또한 button1을 클릭했을 때 가상 함수 setRandomColor()를 호출하는 상호작용을 설정했습니다.

TouchGFX Designer 애플리케이션

버튼을 누를 때마다 배경 박스의 색상이 새로운 색상으로 무작위로 바뀌도록 만들어보겠습니다. 이러한 동작을 사용자 코드에 구현하여 사용자 정의 코드의 작성 방법을 시연하겠습니다.

계층

이 예에서 연관된 여러 클래스가 아래와 같이 보일 수 있습니다.

클래스 예시

위 그림에서,

  • MyScreenViewBase, FrontendApplicationBaseFrontendHeapBase가 생성 계층에 있는데, 이는 다음을 의미합니다.
    • TouchGFX Designer에서 변경 사항이 생길 때마다 이 기본 클래스들이 다시 생성됩니다.
    • 사용자가 이 클래스를 직접 편집해서는 안 됩니다.
  • MyScreenView, MyScreenPresenter, FrontendApplicationFrontendHeap이 사용자 코드 공간에 생성되는데, 이는 다음을 의미합니다.
    • 이 코드들은 TouchGFX Designer에서 변경 사항이 생기더라도 다시 생성되지 않습니다.
    • 사용자는 여기서 사용자 정의 코드를 자유롭게 추가할 수 있습니다.
  • box1button1 설정은 모두 생성된 view 기반 클래스인 MyScreenViewBase에서 이루어집니다.
  • 스크린 전환 시 호출되는 모든 함수는 생성된 애플리케이션 기반 클래스인 FrontendApplicationBase에 위치합니다.
  • 적정량의 메모리가 할당되도록 하는 모든 기록은 생성된 힙 기반 클래스인 FrontendHeapBase에 위치합니다.

사용자는 사용자 코드 클래스를 자유롭게 편집할 수 있습니다. 예를 들어 위젯을 더 추가할 수 있습니다. 여기서는 setRandomColor 함수만 실행하여 box1의 색상의 변경해보겠습니다.

코드

view 기반 코드를 보면 TouchGFX Designer에서 생성되는 박스와 버튼에 대한 설정이 있습니다. 또한 buttonCallbackHandlersetRandomColor 가상 함수에 대한 설정과 호출도 있지만 여기서는 이 함수가 아무런 기능도 하지 않습니다.

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에서 생성되는 코드 기능을 꼭 사용해야 하는 것은 아니지만 이 기능을 사용하면 상당한 시간을 아낄 수 있습니다. 필요한 파일만 직접 추가해서 기존의 방식으로 TouchGFX 애플리케이션을 생성할 수도 있습니다.

또한 여러 가지를 혼합해서 조화롭게 생성하는 것도 가능합니다. 예를 들어 TouchGFX Designer 프로젝트에서 정의하지 않는 스크린도 넣을 수 있습니다. 그 밖에 gotoXYZ 함수를 FrontendApplication 클래스에 추가하거나 사용자 스크린에 필요한 view, presenter 그리고 전환을 FrontendHeap 에 추가할 수 있습니다.