add axes in web view
[scilab.git] / scilab / modules / graphic_objects / src / cpp / ScilabWebView.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2016 - Scilab Enterprises - Antoine ELIAS
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 #include "ScilabWebView.hxx"
17 #include "CallGraphicController.hxx"
18 #include "configvariable.hxx"
19 #include "webutils.hxx"
20
21 extern "C"
22 {
23 #include "getScilabJavaVM.h"
24 #include "getGraphicObjectProperty.h"
25 #include "graphicObjectProperties.h"
26 #include "storeCommand.h"
27 }
28
29 #ifdef _MSC_VER
30 #ifdef _DEBUG
31 #pragma comment(lib,"sioclientd.lib")
32 #else
33 #pragma comment(lib,"sioclient.lib")
34 #endif
35 #endif
36
37 ScilabWebView* ScilabWebView::me = nullptr;
38
39 void ScilabNativeWebView__createObject(int uid)
40 {
41     ScilabWebView::getInstance()->createObject(uid);
42 }
43
44 void ScilabNativeWebView__deleteObject(int uid)
45 {
46     ScilabWebView::getInstance()->deleteObject(uid);
47 }
48
49 void ScilabNativeWebView__updateObject(int uid, int prop)
50 {
51     ScilabWebView::getInstance()->updateObject(uid, prop);
52 }
53
54 void ScilabWebView::registerToController(void)
55 {
56     if (ConfigVariable::getGraphicAddress().empty())
57     {
58         return;
59     }
60
61     //register view in graphic MVC
62     org_scilab_modules_graphic_objects::CallGraphicController::registerScilabWebView(getScilabJavaVM());
63
64     //set and start sioclient
65     //bind main event on socket
66     client.set_open_listener(std::bind(&graphic_listener::on_connected, &l));
67     client.set_close_listener(std::bind(&graphic_listener::on_close, &l, std::placeholders::_1));
68     client.set_fail_listener(std::bind(&graphic_listener::on_fail, &l));
69
70     //connect it
71     client.connect(ConfigVariable::getGraphicAddress());
72
73     //wait connection OK
74     l.lock.lock();
75     if (!l.connect_finish)
76     {
77         l.cond.wait(l.lock);
78     }
79
80     l.lock.unlock();
81
82     //get connected socket
83     s = client.socket();
84
85     s->on("closeWindow", sio::socket::event_listener_aux([&](std::string const & name, sio::message::ptr const & data, bool isAck, sio::message::list & ack_resp)
86     {
87         l.lock.lock();
88         int uid = (int)data->get_map()["uid"]->get_int();
89         WebUtils::deleteGraphicObject(uid);
90         l.cond.notify_all();
91         l.lock.unlock();
92     }));
93
94     s->on("imagepath", sio::socket::event_listener_aux([&](std::string const & name, sio::message::ptr const & data, bool isAck, sio::message::list & ack_resp)
95     {
96         l.lock.lock();
97         std::string path = (std::string)data->get_map()["path"]->get_string();
98         WebUtils::setImagePath(path);
99         l.cond.notify_all();
100         l.lock.unlock();
101     }));
102
103     s->on("callback", sio::socket::event_listener_aux([&](std::string const & name, sio::message::ptr const & data, bool isAck, sio::message::list & ack_resp)
104     {
105         l.lock.lock();
106         int uid = (int)data->get_map()["uid"]->get_int();
107
108         switch (WebUtils::getStyle(uid))
109         {
110             case __GO_UI_PUSHBUTTON__:
111                 //nothing to update, exec callback only
112                 break;
113             case __GO_UI_CHECKBOX__:
114             case __GO_UI_RADIOBUTTON__:
115             {
116                 //get checked status
117                 bool status = data->get_map()["value"]->get_bool();
118                 WebUtils::updateValue(uid, status);
119                 break;
120             }
121             case __GO_UI_POPUPMENU__:
122             case __GO_UI_LISTBOX__:
123             {
124                 std::vector<double> d;
125                 std::vector<sio::message::ptr> v = data->get_map()["value"]->get_vector();
126                 for (auto it : v)
127                 {
128                     d.push_back(it->get_double() + 1); //1 indexed
129                 }
130
131                 WebUtils::updateValue(uid, d);
132                 break;
133             }
134             break;
135             case __GO_UI_EDIT__:
136             {
137                 std::string value = (std::string)data->get_map()["value"]->get_string();
138                 WebUtils::updateValue(uid, value);
139                 break;
140             }
141             case __GO_UI_SLIDER__:
142             case __GO_UI_SPINNER__:
143             {
144                 double value = (double)data->get_map()["value"]->get_double();
145                 WebUtils::updateValue(uid, value);
146                 break;
147             }
148
149             case __GO_UI_TAB__:
150             {
151                 double value = (double)data->get_map()["value"]->get_int();
152                 WebUtils::updateValue(uid, value);
153                 break;
154             }
155         }
156
157         l.cond.notify_all();
158         l.lock.unlock();
159
160         //get calltype type and callback instruction from MVC
161         int cbtype = WebUtils::getIntProperty(uid, __GO_CALLBACKTYPE__);
162         std::string cb = WebUtils::getStringProperty(uid, __GO_CALLBACK__);
163
164         if (cbtype == -1)
165         {
166             return;
167         }
168
169         std::string str;
170         str = "if exists(\"gcbo\") then %oldgcbo = gcbo; end;";
171         str += "gcbo = getcallbackobject(" + std::to_string(uid) + ");";
172         str += cb;
173         str += ";if exists(\"%oldgcbo\") then gcbo = %oldgcbo; else clear gcbo; end;";
174
175         if (cbtype == 10 || cbtype == 12)
176         {
177             StorePrioritaryCommand((char*)str.data());
178         }
179         else
180         {
181             StoreCommand((char*)str.data());
182         }
183     }));
184
185     WebUtils::fillSetters();
186 }
187
188 void ScilabWebView::unregisterToController(void)
189 {
190     org_scilab_modules_graphic_objects::CallGraphicController::unregisterScilabWebView(getScilabJavaVM());
191
192     client.sync_close();
193     client.clear_con_listeners();
194
195 }
196
197
198 void ScilabWebView::createObject(int uid)
199 {
200     std::ostringstream ostr;
201     switch (WebUtils::getType(uid))
202     {
203         case __GO_FIGURE__:
204             WebUtils::createFigure(uid, ostr);
205             break;
206         case __GO_UICONTROL__:
207             WebUtils::createUIControl(uid, ostr);
208             WebUtils::updateDefaultProperties(uid, ostr);
209             break;
210         case __GO_AXES__ :
211             WebUtils::createAxes(uid, ostr);
212             break;
213         default:
214             return;
215     }
216
217     s->emit("graphic_create", ostr.str());
218 }
219
220 void ScilabWebView::deleteObject(int uid)
221 {
222     std::ostringstream ostr;
223     WebUtils::deleteObject(uid, ostr);
224     s->emit("graphic_delete", ostr.str());
225 }
226
227 void ScilabWebView::updateObject(int uid, int prop)
228 {
229     std::ostringstream ostr;
230     switch (WebUtils::getType(uid))
231     {
232         case __GO_FIGURE__ :
233             if (WebUtils::setFigureProperty(prop, uid, ostr) == false)
234             {
235                 return;
236             }
237             break;
238         case __GO_AXES__ :
239             std::cerr << "axes prop:" << prop << std::endl;
240             if (WebUtils::setAxesProperty(prop, uid, ostr) == false)
241             {
242                 return;
243             }
244             break;
245         case __GO_UICONTROL__:
246             if (WebUtils::hasValidParent(uid) || prop == __GO_PARENT__)
247             {
248                 if (WebUtils::setUIControlProperty(prop, uid, ostr) == false)
249                 {
250                     return;
251                 }
252             }
253             else
254             {
255                 //parent is not already set, put update in waiting queue
256                 WebUtils::addInWaitingQueue(uid, prop);
257                 return;
258             }
259             break;
260     }
261
262     s->emit("graphic_update", ostr.str());
263 }