|
在学习touchgfx之前先了解MVP模式:
MVP模式实现数据,主导器控制数据逻辑,视图三者分离,体现在touchgfx中UML图如下:
程序该部分实现如下:
一个程序只有一个model,可以有多对presenter和view。
下面再看touchgfx主要基类Drawable:
在touchgfx中控件都直接或间接派生于Drawable类,Drawable类实际也实现了对控件的管理作用。可以发现touchgfx的控件管理结构和早期的ucgui结构很类似。下面是ucgui的结构,可以帮助理解。parent相当于hparent,nextslibling相当于hNextLin,nextRrawChainElement相当于hNext,firstchild相当于hfirstchild:
Touchgfx中container或继承于container的控件与ucgui中window类似。
当得到触摸屏触点坐标后,可以遍历此链表,得到最上层和触点坐标符合的控件,通常是先进行初步信息处理,然后回调绑定的回调函数。
现在以button的为例说明:
Model部分:
Model是数据部分,为给presenter提供数据操作,所以必须提供set_,get_接口。然后考虑到数据异常或如tickevent等问题,有必要提供接口通知presenter,具体做法是在类ModelListener中提供接口,然后在model及用户的present(用户present继承于present和ModelListener)中实现,通过多态可实现一个model中调用同一名称函数实现多种功能。
User_Presenter部分:
Presenter是数据处理和程序逻辑控制部分,在这部分里要实现比如通知view显示数据,把与用户交互得到数据写到model部分等功能。
在mainpresenter中声明了两个button的行为函数,在实现中调用view方法和model方式进行输出和储存处理。
User_view部分:
该部分主要是调用控件属性函数控制控件的行为,通知与之相对的present部分。从以下声明中可看出具体用到的控件在view部分中声明。既然有控件也要给控件绑定用户想要实现的功能,所以有回调函数模版类的存在。setupScreen函数在Screen中声明为虚函数,供子类实例化,和present中的active函数一起被调用,下面会见到。
以上setupScreen中add函数在对诸如container类或其继承类中应为<Widget>.add(widget),如container contain;contain.add(upbutton);
最后一部分就是FrontendApplication了,它负责screen的转换,也即实现model的重新绑定。
voidFrontendApplication::gotoMainScreen()
{
transitionCallback = Callback<FrontendApplication >(this, &FrontendApplication::gotoMainScreenImpl); ;
pendingScreenTransitionCallback =&transitionCallback;
}
voidFrontendApplication::gotoMainScreenImpl()
{
makeTransition< MainView, MainPresenter,NoTransition, Model >(¤tScreen, ¤tPresenter,frontendHeap, ¤tTransition, &model);
}
Callback<FrontendApplication>transitionCallback;
GenericCallback<>*pendingScreenTransitionCallback; ///< Callback for screen transitions. Willbe set to something valid when a transition request is made.
从pendingScreenTransitionCallback注释可以看出这是将要调用的view回调函数。
gotoMainScreenImpl函数是present和view绑定的具体实现。
voidFrontendApplication::___Screen()
voidFrontendApplication::___ScreenImpl()
这样函数成对出现,也是C++惯用手法。
现在看voidFrontendApplication::gotoMainScreenImpl()中makeTransition函数模版,template<class ScreenType, class PresenterType, class TransType, class ModelType >
PresenterType*makeTransition(Screen** currentScreen, Presenter** currentPresenter,MVPHeap& heap, Transition** currentTrans, ModelType* model)
{
*currentTrans = newTransition;
*currentPresenter = newPresenter;
*currentScreen = newScreen;
model->bind(newPresenter); //绑定新的present
newPresenter->bind(model);//bind
newScreen->bind(*newPresenter);//bind
finalizeTransition((Screen*) newScreen,(Presenter*) newPresenter, (Transition*) newTransition);
}
它实现现有screen的切出和将要切换screen的切入。
其中调用函数
finalizeTransition((Screen*)newScreen, (Presenter*) newPresenter, (Transition*) newTransition);
static inlinevoid finalizeTransition(Screen* newScreen, Presenter* newPresenter, Transition*newTransition){
newScreen->setupScreen();
newPresenter->activate();
newScreen->bindTransition(*newTransition);
newTransition->init();
Application::getInstance()->draw();
}
还有就是screen的初始入口了,它位于FrontendHeap.hpp中
最后来看看touchgfx在应用中何处被实例化
剩下的就是消息循环了,这个在没源码情况下很难分析,猜测和Qt消息循环差不多,找到控件,派发一系列消息到控件,调用控件绑定的回调函数诸如此类。
|
|