blob: 4d492f488c493849a72bc609510201a6a1e49124 [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:
halcanary96fcdcc2015-08-27 07:41:13 -070042 LuaView() : fLua(nullptr) {}
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +000043
halcanary385fe4d2015-08-26 13:07:48 -070044 virtual ~LuaView() { delete fLua; }
reed@google.com3597b732013-05-22 20:12:50 +000045
reed09445a42014-10-10 20:31:24 -070046 void setImageFilename(lua_State* L) {
47 SkString str = GetResourcePath("mandrill_256.png");
48
49 lua_getglobal(L, "setImageFilename");
50 if (lua_isfunction(L, -1)) {
51 fLua->pushString(str.c_str());
52 if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
53 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
54 }
55 }
56 }
57
reed@google.com3597b732013-05-22 20:12:50 +000058 lua_State* ensureLua() {
halcanary96fcdcc2015-08-27 07:41:13 -070059 if (nullptr == fLua) {
halcanary385fe4d2015-08-26 13:07:48 -070060 fLua = new SkLua;
reed09445a42014-10-10 20:31:24 -070061
reed18ea7772014-10-11 11:28:07 -070062 SkString str = GetResourcePath(LUA_FILENAME);
bungeman38d909e2016-08-02 14:40:46 -070063 sk_sp<SkData> data(SkData::MakeFromFileName(str.c_str()));
reed09445a42014-10-10 20:31:24 -070064 if (data) {
65 fLua->runCode(data->data(), data->size());
reed09445a42014-10-10 20:31:24 -070066 this->setImageFilename(fLua->get());
67 } else {
68 fLua->runCode(gMissingCode);
69 }
reed@google.com3597b732013-05-22 20:12:50 +000070 }
71 return fLua->get();
72 }
73
74protected:
mtklein36352bf2015-03-25 18:17:31 -070075 bool onQuery(SkEvent* evt) override {
reed@google.com3597b732013-05-22 20:12:50 +000076 if (SampleCode::TitleQ(*evt)) {
77 SampleCode::TitleR(evt, "Lua");
78 return true;
79 }
80 SkUnichar uni;
81 if (SampleCode::CharQ(*evt, &uni)) {
reed09a1d672014-10-11 13:13:11 -070082 lua_State* L = this->ensureLua();
83 lua_getglobal(L, gUnicharName);
84 if (lua_isfunction(L, -1)) {
85 SkString str;
86 str.appendUnichar(uni);
87 fLua->pushString(str.c_str());
88 if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
89 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
90 } else {
91 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
halcanary96fcdcc2015-08-27 07:41:13 -070092 this->inval(nullptr);
reed09a1d672014-10-11 13:13:11 -070093 return true;
94 }
95 }
96 }
reed@google.com3597b732013-05-22 20:12:50 +000097 }
98 return this->INHERITED::onQuery(evt);
99 }
100
mtklein36352bf2015-03-25 18:17:31 -0700101 void onDrawContent(SkCanvas* canvas) override {
reed@google.com3597b732013-05-22 20:12:50 +0000102 lua_State* L = this->ensureLua();
103
104 lua_getglobal(L, gDrawName);
105 if (!lua_isfunction(L, -1)) {
106 int t = lua_type(L, -1);
107 SkDebugf("--- expected %s function %d, ignoring.\n", gDrawName, t);
108 lua_pop(L, 1);
109 } else {
110 // does it make sense to try to "cache" the lua version of this
111 // canvas between draws?
112 fLua->pushCanvas(canvas);
reedbdc49ae2014-10-14 09:34:52 -0700113 fLua->pushScalar(this->width());
114 fLua->pushScalar(this->height());
115 if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
reed@google.com3597b732013-05-22 20:12:50 +0000116 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
reed18ea7772014-10-11 11:28:07 -0700117 } else {
118 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700119 this->inval(nullptr);
reed18ea7772014-10-11 11:28:07 -0700120 }
reed@google.com3597b732013-05-22 20:12:50 +0000121 }
122 }
reed@google.com3597b732013-05-22 20:12:50 +0000123 }
124
125 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
mtklein36352bf2015-03-25 18:17:31 -0700126 unsigned modi) override {
reed18ea7772014-10-11 11:28:07 -0700127 lua_State* L = this->ensureLua();
128 lua_getglobal(L, gClickName);
129 if (lua_isfunction(L, -1)) {
130 fLua->pushScalar(x);
131 fLua->pushScalar(y);
reed7a72c672014-11-07 10:23:55 -0800132 fLua->pushString("down");
133 if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
reed18ea7772014-10-11 11:28:07 -0700134 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
135 } else {
136 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700137 this->inval(nullptr);
reed7a72c672014-11-07 10:23:55 -0800138 Click* c = new Click(this);
139 c->setType(gLuaClickHandlerName);
140 return c;
reed18ea7772014-10-11 11:28:07 -0700141 }
142 }
143 }
reed@google.com3597b732013-05-22 20:12:50 +0000144 return this->INHERITED::onFindClickHandler(x, y, modi);
145 }
146
mtklein36352bf2015-03-25 18:17:31 -0700147 bool onClick(Click* click) override {
reed7a72c672014-11-07 10:23:55 -0800148 if (click->getType() != gLuaClickHandlerName) {
149 return this->INHERITED::onClick(click);
150 }
151
halcanary96fcdcc2015-08-27 07:41:13 -0700152 const char* state = nullptr;
reed7a72c672014-11-07 10:23:55 -0800153 switch (click->fState) {
154 case Click::kMoved_State:
155 state = "moved";
156 break;
157 case Click::kUp_State:
158 state = "up";
159 break;
160 default:
161 break;
162 }
163 if (state) {
halcanary96fcdcc2015-08-27 07:41:13 -0700164 this->inval(nullptr);
reed7a72c672014-11-07 10:23:55 -0800165 lua_State* L = fLua->get();
166 lua_getglobal(L, gClickName);
167 fLua->pushScalar(click->fCurr.x());
168 fLua->pushScalar(click->fCurr.y());
169 fLua->pushString(state);
170 lua_pcall(L, 3, 1, 0);
171 return lua_isboolean(L, -1) && lua_toboolean(L, -1);
172 }
173 return true;
reed@google.com3597b732013-05-22 20:12:50 +0000174 }
175
176private:
177 SkLua* fLua;
178
179 typedef SampleView INHERITED;
180};
181
182//////////////////////////////////////////////////////////////////////////////
183
184static SkView* MyFactory() { return new LuaView; }
185static SkViewRegister reg(MyFactory);