-
Notifications
You must be signed in to change notification settings - Fork 4
/
CanvasEngine.cc
130 lines (103 loc) · 3.74 KB
/
CanvasEngine.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <typeinfo>
#include "CanvasEngine.h"
#include <Evas_Engine_Software_X11.h>
//#include <Evas_Engine_GL_X11.h>
CanvasEngine *CanvasEngine::instance = nullptr;
CanvasEngine &CanvasEngine::get() {
if (!instance)
throw "CanvasEngine must be initialized first";
return *CanvasEngine::instance;
}
void CanvasEngine::init(Xwindow &frame) {
if (instance)
throw "CanvasEngine was already initialized";
instance = new CanvasEngine(frame);
}
CanvasEngine::CanvasEngine(Xwindow &frame) : canvas(nullptr), widgets() {
Evas_Engine_Info_Software_X11 *einfo;
int32_t method;
evas_init();
if (!(method = evas_render_method_lookup("software_x11")))
throw "ERROR: evas was not compiled with 'software_x11' engine!";
if (!(canvas = evas_new()))
throw "ERROR: could not instantiate new evas canvas.";
evas_output_method_set(canvas, method);
evas_output_size_set(canvas, frame.width(), frame.height());
evas_output_viewport_set(canvas, 0, 0, frame.width(), frame.height());
if (!(einfo =
(Evas_Engine_Info_Software_X11 *)evas_engine_info_get(canvas))) {
evas_free(canvas);
throw "ERROR: could not get evas engine info!";
}
einfo->info.connection = frame.getDisplay();
einfo->info.visual = frame.getVisual();
einfo->info.colormap = frame.getColormap();
einfo->info.drawable = frame.getWindow();
einfo->info.depth = frame.getDepth();
einfo->info.destination_alpha = 1;
einfo->info.debug = 0;
if (!evas_engine_info_set(canvas, (Evas_Engine_Info *)einfo)) {
evas_free(canvas);
throw "ERROR: failed to set evas engine info.";
}
}
void CanvasEngine::resize(const Size &s) {
evas_output_size_set(canvas, s.x, s.y);
evas_output_viewport_set(canvas, 0, 0, s.x, s.y);
}
CanvasEngine::~CanvasEngine() {
// evas widget objects are destructed on the CanvasWidget destructor
widgets.clear();
evas_free(canvas);
}
CanvasWidget &CanvasEngine::addWidget(const std::string &path,
const Layout &layout) {
Evas_Object *image = evas_object_image_filled_add(canvas);
evas_object_image_file_set(image, path.c_str(), nullptr);
if (evas_object_image_load_error_get(image) != EVAS_LOAD_ERROR_NONE)
throw "ERROR: failed to load image.";
// HINT: disable smooth scaling for slow machines
evas_object_image_smooth_scale_set(image, EINA_TRUE);
evas_object_image_alpha_set(image, EINA_TRUE);
evas_object_show(image);
widgets.push_back(new CanvasWidget(image, layout));
return *widgets.back();
}
void CanvasEngine::render() const {
for (const auto &elem : widgets) {
(elem)->render();
}
evas_render(canvas);
}
/////////////////////// CanvasWidget /////////////////////
CanvasWidget::~CanvasWidget() {
if (layout)
delete layout;
layout = nullptr;
if (image)
evas_object_del(image);
image = nullptr;
}
CanvasWidget::CanvasWidget(Evas_Object *img, const Layout &l)
: image(img), layout(nullptr) {
if (typeid(l) == typeid(RectLayout)) {
layout = new RectLayout(dynamic_cast<const RectLayout &>(l));
} else if (typeid(l) == typeid(Layout3D)) {
layout = new Layout3D(dynamic_cast<const Layout3D &>(l));
} else {
throw "CanvasWidget: couldn't identify virtual layout.";
}
}
void CanvasWidget::render() const { layout->transform(image); }
void CanvasWidget::setFrame(const Border &b) {
evas_object_image_border_set(image, b.left, b.right, b.top, b.bottom);
}
///////////////////// Layouts ////////////////////////////
Layout::~Layout() {}
RectLayout::RectLayout(const Rect &r) : layout(r) {}
void RectLayout::transform(Evas_Object *img) const {
evas_object_resize(img, layout.width, layout.height);
evas_object_move(img, layout.x, layout.y);
}
Layout3D::Layout3D(const Rect3D &r) : layout(r) {}
void Layout3D::transform(Evas_Object *) const {}