Skip to content

Commit 0a3e4ba

Browse files
committed
Added ViewElement and ViewButton
1 parent 2fb1fed commit 0a3e4ba

File tree

3 files changed

+102
-1
lines changed

3 files changed

+102
-1
lines changed

include/GameView.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,47 @@
11
#ifndef GAME_VIEW_H
22
#define GAME_VIEW_H
33

4+
#include <vector>
5+
#include <memory>
6+
47
#include "SDL2/SDL.h"
8+
#include "SDL2/SDL_opengl.h"
9+
#include "GL/gl.h"
510

611
#include "GameVisitor.h"
712
#include "Util.h"
813

914
class GameBoard;
1015
class GameController;
16+
class ViewElement;
17+
class GameView;
18+
19+
class ViewElement {
20+
private:
21+
GameView& view;
22+
std::pair<ScreenCoordinate, ScreenCoordinate> rect;
23+
24+
ViewElement(const ViewElement& vw) : view(vw.view) {} //deleted
25+
ViewElement& operator=(const ViewElement&) { return *this; } // deleted
26+
protected:
27+
virtual bool clicked(ScreenCoordinate coord) = 0;
28+
public:
29+
ViewElement(GameView& view, decltype(rect) rect);
30+
virtual ~ViewElement();
31+
32+
virtual decltype(rect) getRect() const;
33+
virtual bool containsPoint(ScreenCoordinate coord) const;
34+
virtual bool handleClick(ScreenCoordinate coord);
35+
virtual void render() = 0;
36+
};
1137

1238
class GameView {
1339
private:
1440
GameBoard& model;
1541
GameController& controller;
1642

43+
std::vector<std::unique_ptr<ViewElement>> viewElements;
44+
1745
GameView(const GameView& o) : model(o.model), controller(o.controller) {} //deleted
1846
GameView& operator=(const GameView& o) { return *this; } //deleted
1947
public:
@@ -55,4 +83,34 @@ class ClickCoordinateEvent {
5583
Coordinate getCoordinate() const;
5684
};
5785

86+
template<class Fn>
87+
class ViewButton : public ViewElement {
88+
private:
89+
Fn action;
90+
std::tuple<float, float, float> color;
91+
92+
ViewButton(const ViewButton& vb) : ViewElement(vb) {} //deleted
93+
ViewButton& operator=(const ViewButton& vb) { return *this; }
94+
protected:
95+
virtual bool clicked(ScreenCoordinate coord) {
96+
return action(coord);
97+
}
98+
public:
99+
ViewButton(Fn& action, std::pair<ScreenCoordinate, ScreenCoordinate> rect, std::tuple<float, float, float> color) : ViewElement(rect), action(action), color(color) {}
100+
~ViewButton() {}
101+
102+
void render() {
103+
glBindTexture(GL_TEXTURE_2D, 0);
104+
glColor3f(std::get<0>(color), std::get<1>(color), std::get<2>(color));
105+
auto topLeft = getRect().first;
106+
auto bottomRight = getRect().second;
107+
glBegin(GL_QUADS);
108+
glVertex3f(topLeft.first, topLeft.second);
109+
glVertex3f(bottomRight.first, topLeft.second);
110+
glVertex3f(bottomRight.first, bottomRight.second);
111+
glVertex3f(topLeft.first, bottomRight.second);
112+
glEnd();
113+
}
114+
};
115+
58116
#endif

include/Util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <sstream>
66

77
typedef std::pair<int, int> Coordinate;
8+
typedef std::pair<float, float> ScreenCoordinate;
89

910
template<class T>
1011
T fromString(const std::string& s) {

src/GameView.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,38 @@ using std::pair;
1515
using std::runtime_error;
1616
using std::string;
1717

18+
ViewElement::ViewElement(GameView& view, decltype(rect) rect) : view(view) {
19+
using std::min;
20+
using std::max;
21+
22+
//rect.first is the min x/min y corner
23+
//rect.second is the max x/max y corner
24+
this->rect.first = {min(rect.first.first, rect.second.first), min(rect.first.second, rect.second.second)};
25+
this->rect.second = {max(rect.first.first, rect.second.first), max(rect.first.second, rect.second.second)};
26+
}
27+
28+
ViewElement::~ViewElement() {
29+
30+
}
31+
32+
decltype(ViewElement::rect) ViewElement::getRect() const {
33+
return rect;
34+
}
35+
36+
bool ViewElement::containsPoint(ScreenCoordinate coord) const {
37+
return rect.first.first < coord.first &&
38+
rect.first.second < coord.second &&
39+
coord.first < rect.second.first &&
40+
coord.second < rect.second.second;
41+
}
42+
43+
bool ViewElement::handleClick(ScreenCoordinate coord) {
44+
if(containsPoint(coord)) {
45+
return clicked(coord);
46+
}
47+
return false;
48+
}
49+
1850
GameView::GameView(GameBoard& model, GameController& controller) : model(model), controller(controller) {
1951

2052
}
@@ -29,14 +61,24 @@ void GameView::render() {
2961
DrawingGameVisitor visitor(*this);
3062
model.accept(visitor);
3163

64+
for(auto& it : viewElements) {
65+
it->render();
66+
}
67+
3268
glFlush();
3369
}
3470

3571
bool GameView::acceptInput(SDL_Event& event) {
3672
if(event.type == SDL_QUIT) {
3773
return false;
3874
} else if(event.type == SDL_MOUSEBUTTONUP) {
39-
controller.handleEvent(ClickCoordinateEvent(screenToCoord({(float) event.button.x / 900.f, 1.f - (float) event.button.y / 800.f})));
75+
ScreenCoordinate screen = {(float) event.button.x / 900.f, 1.f - (float) event.button.y / 800.f};
76+
for(auto& it : viewElements) {
77+
if(it->handleClick(screen)) {
78+
return true;
79+
}
80+
}
81+
controller.handleEvent(ClickCoordinateEvent(screenToCoord(screen)));
4082
}
4183
return true;
4284
}

0 commit comments

Comments
 (0)