blob: 81ac6aef0d9ee096cde6ef9da6a1ac94cec8ee3a [file] [log] [blame]
reed@google.com3597b732013-05-22 20:12:50 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SampleCode.h"
9#include "SkView.h"
10#include "SkLua.h"
11#include "SkCanvas.h"
reed09445a42014-10-10 20:31:24 -070012#include "Resources.h"
13#include "SkData.h"
reed@google.com3597b732013-05-22 20:12:50 +000014
15extern "C" {
16#include "lua.h"
17#include "lualib.h"
18#include "lauxlib.h"
19}
20
reed9fbc3f32014-10-21 07:12:58 -070021//#define LUA_FILENAME "test.lua"
22#define LUA_FILENAME "slides.lua"
reed18ea7772014-10-11 11:28:07 -070023
reed@google.com3597b732013-05-22 20:12:50 +000024static const char gDrawName[] = "onDrawContent";
reed18ea7772014-10-11 11:28:07 -070025static const char gClickName[] = "onClickHandler";
reed09a1d672014-10-11 13:13:11 -070026static const char gUnicharName[] = "onCharHandler";
reed@google.com3597b732013-05-22 20:12:50 +000027
reed7a72c672014-11-07 10:23:55 -080028static const char gLuaClickHandlerName[] = "lua-click-handler";
29
reed09445a42014-10-10 20:31:24 -070030static const char gMissingCode[] = ""
31 "local paint = Sk.newPaint()"
32 "paint:setAntiAlias(true)"
33 "paint:setTextSize(30)"
34 ""
35 "function onDrawContent(canvas)"
36 " canvas:drawText('missing \"test.lua\"', 20, 50, paint)"
37 "end"
38 ;
reed@google.com3597b732013-05-22 20:12:50 +000039
40class LuaView : public SampleView {
41public:
42 LuaView() : fLua(NULL) {}
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +000043
reed@google.com3597b732013-05-22 20:12:50 +000044 virtual ~LuaView() {
45 SkDELETE(fLua);
46 }
47
reed09445a42014-10-10 20:31:24 -070048 void setImageFilename(lua_State* L) {
49 SkString str = GetResourcePath("mandrill_256.png");
50
51 lua_getglobal(L, "setImageFilename");
52 if (lua_isfunction(L, -1)) {
53 fLua->pushString(str.c_str());
54 if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
55 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
56 }
57 }
58 }
59
reed@google.com3597b732013-05-22 20:12:50 +000060 lua_State* ensureLua() {
61 if (NULL == fLua) {
62 fLua = SkNEW(SkLua);
reed09445a42014-10-10 20:31:24 -070063
reed18ea7772014-10-11 11:28:07 -070064 SkString str = GetResourcePath(LUA_FILENAME);
reed09445a42014-10-10 20:31:24 -070065 SkData* data = SkData::NewFromFileName(str.c_str());
66 if (data) {
67 fLua->runCode(data->data(), data->size());
68 data->unref();
69 this->setImageFilename(fLua->get());
70 } else {
71 fLua->runCode(gMissingCode);
72 }
reed@google.com3597b732013-05-22 20:12:50 +000073 }
74 return fLua->get();
75 }
76
77protected:
78 virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
79 if (SampleCode::TitleQ(*evt)) {
80 SampleCode::TitleR(evt, "Lua");
81 return true;
82 }
83 SkUnichar uni;
84 if (SampleCode::CharQ(*evt, &uni)) {
reed09a1d672014-10-11 13:13:11 -070085 lua_State* L = this->ensureLua();
86 lua_getglobal(L, gUnicharName);
87 if (lua_isfunction(L, -1)) {
88 SkString str;
89 str.appendUnichar(uni);
90 fLua->pushString(str.c_str());
91 if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
92 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
93 } else {
94 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
95 this->inval(NULL);
96 return true;
97 }
98 }
99 }
reed@google.com3597b732013-05-22 20:12:50 +0000100 }
101 return this->INHERITED::onQuery(evt);
102 }
103
104 virtual void onDrawContent(SkCanvas* canvas) SK_OVERRIDE {
105 lua_State* L = this->ensureLua();
106
107 lua_getglobal(L, gDrawName);
108 if (!lua_isfunction(L, -1)) {
109 int t = lua_type(L, -1);
110 SkDebugf("--- expected %s function %d, ignoring.\n", gDrawName, t);
111 lua_pop(L, 1);
112 } else {
113 // does it make sense to try to "cache" the lua version of this
114 // canvas between draws?
115 fLua->pushCanvas(canvas);
reedbdc49ae2014-10-14 09:34:52 -0700116 fLua->pushScalar(this->width());
117 fLua->pushScalar(this->height());
118 if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
reed@google.com3597b732013-05-22 20:12:50 +0000119 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
reed18ea7772014-10-11 11:28:07 -0700120 } else {
121 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
122 this->inval(NULL);
123 }
reed@google.com3597b732013-05-22 20:12:50 +0000124 }
125 }
reed@google.com3597b732013-05-22 20:12:50 +0000126 }
127
128 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
129 unsigned modi) SK_OVERRIDE {
reed18ea7772014-10-11 11:28:07 -0700130 lua_State* L = this->ensureLua();
131 lua_getglobal(L, gClickName);
132 if (lua_isfunction(L, -1)) {
133 fLua->pushScalar(x);
134 fLua->pushScalar(y);
reed7a72c672014-11-07 10:23:55 -0800135 fLua->pushString("down");
136 if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
reed18ea7772014-10-11 11:28:07 -0700137 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
138 } else {
139 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
140 this->inval(NULL);
reed7a72c672014-11-07 10:23:55 -0800141 Click* c = new Click(this);
142 c->setType(gLuaClickHandlerName);
143 return c;
reed18ea7772014-10-11 11:28:07 -0700144 }
145 }
146 }
reed@google.com3597b732013-05-22 20:12:50 +0000147 return this->INHERITED::onFindClickHandler(x, y, modi);
148 }
149
150 virtual bool onClick(Click* click) SK_OVERRIDE {
reed7a72c672014-11-07 10:23:55 -0800151 if (click->getType() != gLuaClickHandlerName) {
152 return this->INHERITED::onClick(click);
153 }
154
155 const char* state = NULL;
156 switch (click->fState) {
157 case Click::kMoved_State:
158 state = "moved";
159 break;
160 case Click::kUp_State:
161 state = "up";
162 break;
163 default:
164 break;
165 }
166 if (state) {
167 this->inval(NULL);
168 lua_State* L = fLua->get();
169 lua_getglobal(L, gClickName);
170 fLua->pushScalar(click->fCurr.x());
171 fLua->pushScalar(click->fCurr.y());
172 fLua->pushString(state);
173 lua_pcall(L, 3, 1, 0);
174 return lua_isboolean(L, -1) && lua_toboolean(L, -1);
175 }
176 return true;
reed@google.com3597b732013-05-22 20:12:50 +0000177 }
178
179private:
180 SkLua* fLua;
181
182 typedef SampleView INHERITED;
183};
184
185//////////////////////////////////////////////////////////////////////////////
186
187static SkView* MyFactory() { return new LuaView; }
188static SkViewRegister reg(MyFactory);