• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
12 #include "Resources.h"
13 #include "SkData.h"
14 
15 extern "C" {
16 #include "lua.h"
17 #include "lualib.h"
18 #include "lauxlib.h"
19 }
20 
21 //#define LUA_FILENAME    "test.lua"
22 #define LUA_FILENAME    "slides.lua"
23 
24 static const char gDrawName[] = "onDrawContent";
25 static const char gClickName[] = "onClickHandler";
26 static const char gUnicharName[] = "onCharHandler";
27 
28 static const char gLuaClickHandlerName[] = "lua-click-handler";
29 
30 static 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     ;
39 
40 class LuaView : public SampleView {
41 public:
LuaView()42     LuaView() : fLua(nullptr) {}
43 
~LuaView()44     virtual ~LuaView() { delete fLua; }
45 
setImageFilename(lua_State * L)46     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 
ensureLua()58     lua_State* ensureLua() {
59         if (nullptr == fLua) {
60             fLua = new SkLua;
61 
62             SkString str = GetResourcePath(LUA_FILENAME);
63             sk_sp<SkData> data(SkData::MakeFromFileName(str.c_str()));
64             if (data) {
65                 fLua->runCode(data->data(), data->size());
66                 this->setImageFilename(fLua->get());
67             } else {
68                 fLua->runCode(gMissingCode);
69             }
70         }
71         return fLua->get();
72     }
73 
74 protected:
onQuery(SkEvent * evt)75     bool onQuery(SkEvent* evt) override {
76         if (SampleCode::TitleQ(*evt)) {
77             SampleCode::TitleR(evt, "Lua");
78             return true;
79         }
80         SkUnichar uni;
81         if (SampleCode::CharQ(*evt, &uni)) {
82             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)) {
92                         this->inval(nullptr);
93                         return true;
94                     }
95                 }
96             }
97         }
98         return this->INHERITED::onQuery(evt);
99     }
100 
onDrawContent(SkCanvas * canvas)101     void onDrawContent(SkCanvas* canvas) override {
102         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);
113             fLua->pushScalar(this->width());
114             fLua->pushScalar(this->height());
115             if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
116                 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
117             } else {
118                 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
119                     this->inval(nullptr);
120                 }
121             }
122         }
123     }
124 
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)125     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
126                                               unsigned modi) override {
127         lua_State* L = this->ensureLua();
128         lua_getglobal(L, gClickName);
129         if (lua_isfunction(L, -1)) {
130             fLua->pushScalar(x);
131             fLua->pushScalar(y);
132             fLua->pushString("down");
133             if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
134                 SkDebugf("lua err: %s\n", lua_tostring(L, -1));
135             } else {
136                 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
137                     this->inval(nullptr);
138                     Click* c = new Click(this);
139                     c->setType(gLuaClickHandlerName);
140                     return c;
141                 }
142             }
143         }
144         return this->INHERITED::onFindClickHandler(x, y, modi);
145     }
146 
onClick(Click * click)147     bool onClick(Click* click) override {
148         if (click->getType() != gLuaClickHandlerName) {
149             return this->INHERITED::onClick(click);
150         }
151 
152         const char* state = nullptr;
153         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) {
164             this->inval(nullptr);
165             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;
174     }
175 
176 private:
177     SkLua* fLua;
178 
179     typedef SampleView INHERITED;
180 };
181 
182 //////////////////////////////////////////////////////////////////////////////
183 
MyFactory()184 static SkView* MyFactory() { return new LuaView; }
185 static SkViewRegister reg(MyFactory);
186