Escher: Adding Window, ViewController and TabViewController

Change-Id: I6a13fe95e846cfcc43f783e8b4d88ea4ad9ee585
This commit is contained in:
Romain Goyet
2016-05-25 14:16:47 +02:00
parent da93ac6dfb
commit b79b7b5133
21 changed files with 381 additions and 18 deletions

View File

@@ -1,7 +1,12 @@
SFLAGS += -Iescher/include
objs += $(addprefix escher/src/,\
childless_view.o\
solid_color_view.o\
tab_view.o\
tab_view_controller.o\
text_view.o\
view.o\
view_controller.o\
window.o\
)

View File

@@ -3,6 +3,9 @@
#include <escher/solid_color_view.h>
#include <escher/text_view.h>
#include <escher/tab_view_controller.h>
#include <escher/view.h>
#include <escher/view_controller.h>
#include <escher/window.h>
#endif

View File

@@ -4,9 +4,12 @@
#include <escher/view.h>
class ChildlessView : public View {
using View::View;
protected:
int numberOfSubviews() override;
View * subview(int index) override;
void storeSubviewAtIndex(View * v, int index) override;
void layoutSubviews() override;
};
#endif

View File

@@ -0,0 +1,14 @@
#ifndef ESCHER_MENU_VIEW_H
#define ESCHER_MENU_VIEW_H
#include <escher/view.h>
class MenuView : public View {
public:
MenuView(Menu * menu);
//void drawRect(KDRect rect) override;
//private:
//KDColor m_color;
};
#endif

View File

@@ -1,11 +1,11 @@
#ifndef ESCHER_SOLID_COLOR_VIEW_H
#define ESCHER_SOLID_COLOR_VIEW_H
#include <escher/view.h>
#include <escher/childless_view.h>
class SolidColorView : public View {
class SolidColorView : public ChildlessView {
public:
SolidColorView(KDRect frame, KDColor color);
SolidColorView(KDColor color);
void drawRect(KDRect rect) override;
private:
KDColor m_color;

View File

@@ -0,0 +1,30 @@
#ifndef ESCHER_TAB_VIEW_H
#define ESCHER_TAB_VIEW_H
#include <escher/view.h>
#include <escher/tab_view_cell.h>
class TabViewController;
class TabView : public View {
public:
// We'll ask the TabViewController for its controllers
// and each controller know its name!
// and also the active index !
TabView(TabViewController * tabViewController);
//void drawRect(KDRect rect) override;
int numberOfSubviews() override;
View * subview(int index) override;
void layoutSubviews() override;
protected:
void storeSubviewAtIndex(View * view, int index) override;
private:
TabViewController * m_tabViewController;
/*
static constexpr uint8_t k_maxNumberOfTabs = 4;
uint8_t m_numberOfTabs;
TabViewCell m_cells[k_maxNumberOfTabs];
*/
};
#endif

View File

@@ -0,0 +1,18 @@
#ifndef ESCHER_TAB_VIEW_CELL_H
#define ESCHER_TAB_VIEW_CELL_H
#include <escher/view.h>
#include <escher/text_view.h>
class TabViewCell : public View {
public:
TabViewCell();
int numberOfSubviews() override;
View * subview(int index) override;
void setName(const char * name);
private:
TextView m_textView;
};
#endif

View File

@@ -0,0 +1,38 @@
#ifndef ESCHER_TAB_VIEW_CONTROLLER_H
#define ESCHER_TAB_VIEW_CONTROLLER_H
#include <escher/view_controller.h>
#include <escher/tab_view.h>
class TabViewController : public ViewController {
public:
TabViewController(ViewController ** children);
View * view() override;
void handleKeyEvent(int key) override;
void setActiveTab(uint8_t index);
uint8_t numberOfTabs();
private:
class ContentView : public View {
public:
ContentView(TabViewController * vc);
int numberOfSubviews() override;
View * subview(int index) override;
void storeSubviewAtIndex(View * view, int index) override;
void layoutSubviews() override;
void setActiveView(View * view);
private:
TabView m_tabView;
View * m_activeView;
};
ContentView m_view;
ViewController ** m_children;
uint8_t m_activeChildIndex;
};
#endif

View File

@@ -0,0 +1,18 @@
#ifndef ESCHER_TABLE_VIEW_H
#define ESCHER_TABLE_VIEW_H
#include <escher/view.h>
class TableView : public View {
public:
TableView(
-> DataSource,
-> CellClass
);
TextView(KDPoint origin, const char * text);
void drawRect(KDRect rect) override;
private:
const char * m_text;
};
#endif

View File

@@ -3,9 +3,9 @@
#include <escher/childless_view.h>
class TextView : public View {
class TextView : public ChildlessView {
public:
TextView(KDPoint origin, const char * text);
TextView(const char * text);
void drawRect(KDRect rect) override;
private:
const char * m_text;

View File

@@ -17,20 +17,24 @@ extern "C" {
class View {
public:
View(KDRect frame);
~View();
View();
virtual void drawRect(KDRect rect); // To be implemented. Draw ourself.
//void addSubview(View * subview);
//void removeFromSuperview();
void setFrame(KDRect frame);
void redraw();
void setSubview(View * v, int index);
protected:
KDRect bounds();
virtual bool isOnScreen();
virtual int numberOfSubviews() = 0;
virtual View * subview(int index) = 0;
virtual void storeSubviewAtIndex(View * v, int index) = 0;
virtual void layoutSubviews() = 0;
private:
void redraw();
void redraw(KDRect rect);
KDRect absoluteDrawingArea();

View File

@@ -0,0 +1,24 @@
#ifndef ESCHER_VIEW_CONTROLLER_H
#define ESCHER_VIEW_CONTROLLER_H
extern "C" {
#include <stdint.h>
#include <kandinsky.h>
}
/* ViewControllers are reponsible for
* - Building the view hierarchy
* - Handling user input
*/
#include <escher/view.h>
class ViewController {
public:
ViewController();
virtual char * title();
virtual void handleKeyEvent(int key);
virtual View * view() = 0;
};
#endif

View File

@@ -0,0 +1,19 @@
#ifndef ESCHER_WINDOW_H
#define ESCHER_WINDOW_H
#include <escher/view.h>
class Window : public View {
public:
Window();
protected:
bool isOnScreen() override;
int numberOfSubviews() override;
View * subview(int index) override;
void layoutSubviews() override;
void storeSubviewAtIndex(View * view, int index) override;
private:
View * m_contentView;
};
#endif

View File

@@ -0,0 +1,20 @@
#include <escher/childless_view.h>
extern "C" {
#include <assert.h>
}
int ChildlessView::numberOfSubviews() {
return 0;
}
View * ChildlessView::subview(int index) {
assert(false);
return nullptr;
}
void ChildlessView::layoutSubviews() {
}
void ChildlessView::storeSubviewAtIndex(View * v, int index) {
assert(false);
}

View File

@@ -1,7 +1,7 @@
#include <escher/solid_color_view.h>
SolidColorView::SolidColorView(KDRect frame, KDColor color) :
View(frame),
SolidColorView::SolidColorView(KDColor color) :
ChildlessView(),
m_color(color)
{
}

31
escher/src/tab_view.cpp Normal file
View File

@@ -0,0 +1,31 @@
#include <escher/tab_view.h>
#include <escher/tab_view_controller.h>
TabView::TabView(TabViewController * tabViewController) :
View(),
m_tabViewController(tabViewController)
{
/*
m_numberOfTabs = tabViewController->numberOfTabs();
for (uint8_t i=0; i<m_numberOfTabs; i++) {
//m_cells[i] = TabViewCell(name);
//FIXME: use setName
}
*/
}
int TabView::numberOfSubviews() {
return 0; //FIXME
}
View * TabView::subview(int index) {
return nullptr;
}
void TabView::layoutSubviews() {
// TODO
}
void TabView::storeSubviewAtIndex(View * view, int index) {
// TODO
}

View File

@@ -0,0 +1,67 @@
extern "C" {
#include <assert.h>
}
#include <escher/tab_view_controller.h>
TabViewController::ContentView::ContentView(TabViewController * vc) :
View(),
m_tabView(TabView(vc)),
m_activeView(nullptr)
{
};
void TabViewController::ContentView::setActiveView(View * view) {
setSubview(view, 1);
}
void TabViewController::ContentView::layoutSubviews() {
if (m_activeView) {
m_activeView->setFrame(this->bounds());
}
}
int TabViewController::ContentView::numberOfSubviews() {
return 2;
}
View * TabViewController::ContentView::subview(int index) {
if (index == 0) {
return &m_tabView;
} else {
assert(index == 1);
return m_activeView;
}
}
void TabViewController::ContentView::ContentView::storeSubviewAtIndex(View * view, int index) {
assert(index == 1);
m_activeView = view;
}
TabViewController::TabViewController(ViewController ** children) :
m_children(children),
m_activeChildIndex(0),
m_view(ContentView(this))
{
setActiveTab(0);
}
void TabViewController::setActiveTab(uint8_t i) {
if (i == m_activeChildIndex) {
return;
}
//TODO assert(i <= m_numberOfchildren);
ViewController * activeVC = m_children[i];
m_view.setActiveView(activeVC->view());
m_activeChildIndex = i;
m_view.redraw();
//m_tabView.redraw();
}
View * TabViewController::view() {
return &m_view;
}
void TabViewController::handleKeyEvent(int key) {
// Switch tabs!
}

View File

@@ -1,17 +1,21 @@
#include <escher/text_view.h>
KDRect ViewFrame(KDPoint origin, const char * text) {
/*
KDRect ViewFrame(const char * text) {
KDRect r;
r.origin = origin;
r.size = KDStringSize(text);
return r;
}
*/
TextView::TextView(KDPoint origin, const char * text) :
View(ViewFrame(origin, text)) {
TextView::TextView(const char * text) :
ChildlessView() {
m_text = text;
}
//TODO: implement "setFrame"
void TextView::drawRect(KDRect rect) {
KDPoint zero = {0, 0};
KDDrawString(m_text, zero, 0);

View File

@@ -3,9 +3,9 @@ extern "C" {
}
#include <escher/view.h>
View::View(KDRect frame) :
View::View() :
m_superview(nullptr),
m_frame(frame)
m_frame(KDRectZero)
{
/*
for (uint8_t i=0; i<k_maxNumberOfSubviews; i++) {
@@ -14,19 +14,27 @@ View::View(KDRect frame) :
*/
}
View::~View() {
}
void View::drawRect(KDRect rect) {
// By default, a view doesn't do anything
// It's transparent!
}
bool View::isOnScreen() {
if (m_superview == nullptr) {
return false;
} else {
return m_superview->isOnScreen();
}
}
void View::redraw() {
redraw(bounds());
}
void View::redraw(KDRect rect) {
if (!isOnScreen()) {
return;
}
// Fisrt, let's draw our own content by calling drawRect
KDSetDrawingArea(absoluteDrawingArea());
this->drawRect(rect);
@@ -46,6 +54,17 @@ void View::redraw(KDRect rect) {
}
}
void setSubview(View * v, int index);
void View::setSubview(View * view, int index) {
view->m_superview = this;
storeSubviewAtIndex(view, index);
assert(subview(index) == view);
layoutSubviews();
redraw();
}
/*
void View::addSubview(View * subview) {
// Let's find a spot for that subview
@@ -80,6 +99,7 @@ void View::setFrame(KDRect frame) {
* previously was. So let's redraw that part of the superview. */
m_superview->redraw(previousFrame);
}
layoutSubviews();
// The view now needs to redraw itself entirely
redraw();
}

View File

@@ -0,0 +1,12 @@
#include <escher/view_controller.h>
ViewController::ViewController() {
}
char * ViewController::title() {
return nullptr;
}
void ViewController::handleKeyEvent(int key) {
// Do nothing
}

33
escher/src/window.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include <escher/window.h>
extern "C" {
#include <assert.h>
}
Window::Window() :
m_contentView(nullptr)
{
}
bool Window::isOnScreen() {
return true;
}
int Window::numberOfSubviews() {
return (m_contentView == nullptr ? 0 : 1);
}
View * Window::subview(int index) {
assert(m_contentView != nullptr && index == 0);
return m_contentView;
}
void Window::layoutSubviews() {
if (m_contentView != nullptr) {
m_contentView->setFrame(this->bounds());
}
}
void Window::storeSubviewAtIndex(View * view, int index) {
assert(index == 0);
m_contentView = view;
}