1
// --------------------------------------------------------------------
3
// --------------------------------------------------------------------
6
This file is part of the extensible drawing editor Ipe.
7
Copyright (C) 1993-2009 Otfried Cheong
9
Ipe is free software; you can redistribute it and/or modify it
10
under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 3 of the License, or
12
(at your option) any later version.
14
As a special exception, you have permission to link Ipe with the
15
CGAL library and distribute executables, as long as you follow the
16
requirements of the Gnu General Public License in regard to all of
17
the software in the executable aside from CGAL.
19
Ipe is distributed in the hope that it will be useful, but WITHOUT
20
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
22
License for more details.
24
You should have received a copy of the GNU General Public License
25
along with Ipe; if not, you can find it at
26
"http://www.gnu.org/copyleft/gpl.html", or write to the Free
27
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37
using namespace ipelua;
39
// --------------------------------------------------------------------
41
void ipelua::push_page(lua_State *L, Page *page, bool owned)
43
SPage *p = (SPage *) lua_newuserdata(L, sizeof(SPage));
45
luaL_getmetatable(L, "Ipe.page");
46
lua_setmetatable(L, -2);
50
static int check_objno(lua_State *L, int i, Page *p, int extra = 0)
52
int n = luaL_checkint(L, i);
53
luaL_argcheck(L, 1 <= n && n <= p->count() + extra,
54
i, "invalid object index");
58
int ipelua::check_layer(lua_State *L, int i, Page *p)
60
const char *name = luaL_checkstring(L, i);
61
int l = p->findLayer(name);
62
luaL_argcheck(L, l >= 0, i, "layer does not exist");
66
int ipelua::check_viewno(lua_State *L, int i, Page *p, int extra)
68
int n = luaL_checkint(L, i);
69
luaL_argcheck(L, 1 <= n && n <= p->countViews() + extra,
70
i, "invalid view index");
74
int ipelua::page_constructor(lua_State *L)
76
if (lua_isnoneornil(L, 1)) {
77
push_page(L, Page::basic());
81
const char *p = luaL_checklstring(L, 1, &len);
83
BufferSource source(data);
84
ImlParser parser(source);
85
Page *page = parser.parsePageSelection();
94
static int page_destructor(lua_State *L)
96
SPage *p = check_page(L, 1);
97
if (p->owned && p->page)
103
static int page_index(lua_State *L)
105
Page *p = check_page(L, 1)->page;
106
if (lua_type(L, 2) == LUA_TNUMBER) {
107
int n = check_objno(L, 2, p);
108
push_object(L, p->object(n), false);
110
const char *key = luaL_checkstring(L, 2);
111
if (!luaL_getmetafield(L, 1, key))
117
static int page_tostring(lua_State *L)
120
lua_pushfstring(L, "Page@%p", lua_topointer(L, 1));
124
static int page_len(lua_State *L)
126
Page *p = check_page(L, 1)->page;
127
lua_pushinteger(L, p->count());
131
static int page_clone(lua_State *L)
133
Page *p = check_page(L, 1)->page;
134
push_page(L, new Page(*p), true);
138
// --------------------------------------------------------------------
140
static void push_select(lua_State *L, TSelect sel)
142
if (sel == ENotSelected)
144
else if (sel == EPrimarySelected)
145
lua_pushnumber(L, 1);
147
lua_pushnumber(L, 2);
150
static TSelect check_select(lua_State *L, int index)
152
TSelect w = ENotSelected;
153
if (!lua_isnoneornil(L, index)) {
154
if (luaL_checkint(L, index) == 1)
155
w = EPrimarySelected;
157
w = ESecondarySelected;
162
// arguments: page, counter
163
static int page_object_iterator(lua_State *L)
165
Page *p = check_page(L, 1)->page;
166
int i = luaL_checkint(L, 2);
168
if (i <= p->count()) {
169
lua_pushnumber(L, i); // new counter
170
push_object(L, p->object(i-1), false); // object
171
push_select(L, p->select(i-1));
172
push_string(L, p->layer(p->layerOf(i-1))); // layer
178
// returns object iterator for use in for loop
179
// returns iterator function, invariant state, control variable
180
static int page_objects(lua_State *L)
182
(void) check_page(L, 1);
183
lua_pushcfunction(L, page_object_iterator); // iterator function
184
lua_pushvalue(L, 1); // page
185
lua_pushnumber(L, 0); // counter
189
// --------------------------------------------------------------------
191
static int page_xml(lua_State *L)
193
static const char * const option_names[] =
194
{ "ipepage", "ipeselection", 0 };
195
Page *p = check_page(L, 1)->page;
196
int t = luaL_checkoption(L, 2, 0, option_names);
198
StringStream stream(data);
200
p->saveAsIpePage(stream);
202
p->saveSelection(stream);
203
push_string(L, data);
207
static int page_layers(lua_State *L)
209
Page *p = check_page(L, 1)->page;
210
lua_createtable(L, 0, p->countLayers());
211
for (int i = 0; i < p->countLayers(); ++i) {
212
push_string(L, p->layer(i));
213
lua_rawseti(L, -2, i + 1);
218
static int page_countLayers(lua_State *L)
220
Page *p = check_page(L, 1)->page;
221
lua_pushinteger(L, p->countLayers());
225
static int page_isLocked(lua_State *L)
227
Page *p = check_page(L, 1)->page;
228
int n = check_layer(L, 2, p);
229
lua_pushboolean(L, p->isLocked(n));
233
static int page_hasSnapping(lua_State *L)
235
Page *p = check_page(L, 1)->page;
236
int n = check_layer(L, 2, p);
237
lua_pushboolean(L, p->hasSnapping(n));
241
static int page_setLocked(lua_State *L)
243
Page *p = check_page(L, 1)->page;
244
int n = check_layer(L, 2, p);
245
p->setLocked(n, lua_toboolean(L, 3));
249
static int page_setSnapping(lua_State *L)
251
Page *p = check_page(L, 1)->page;
252
int n = check_layer(L, 2, p);
253
p->setSnapping(n, lua_toboolean(L, 3));
257
static int page_renameLayer(lua_State *L)
259
Page *p = check_page(L, 1)->page;
260
const char *s1 = luaL_checkstring(L, 2);
261
const char *s2 = luaL_checkstring(L, 3);
262
p->renameLayer(s1, s2);
266
static int page_addLayer(lua_State *L)
268
Page *p = check_page(L, 1)->page;
269
if (lua_isnoneornil(L, 2)) {
272
const char *s = luaL_checkstring(L, 2);
275
push_string(L, p->layer(p->countLayers() - 1));
279
static int page_removeLayer(lua_State *L)
281
Page *p = check_page(L, 1)->page;
282
int n = check_layer(L, 2, p);
283
p->removeLayer(p->layer(n));
287
// --------------------------------------------------------------------
289
static int page_select(lua_State *L)
291
Page *p = check_page(L, 1)->page;
292
int n = check_objno(L, 2, p);
293
push_select(L, p->select(n));
297
static int page_setSelect(lua_State *L)
299
Page *p = check_page(L, 1)->page;
300
int n = check_objno(L, 2, p);
301
TSelect w = check_select(L, 3);
306
static int page_layerOf(lua_State *L)
308
Page *p = check_page(L, 1)->page;
309
int n = check_objno(L, 2, p);
310
push_string(L, p->layer(p->layerOf(n)));
314
static int page_setLayerOf(lua_State *L)
316
Page *p = check_page(L, 1)->page;
317
int n = check_objno(L, 2, p);
318
const char *s = luaL_checkstring(L, 3);
319
int l = p->findLayer(s);
320
luaL_argcheck(L, l >= 0, 3, "layer does not exist");
325
static int page_bbox(lua_State *L)
327
Page *p = check_page(L, 1)->page;
328
int n = check_objno(L, 2, p);
329
push_rect(L, p->bbox(n));
333
// use index nil to append
334
static int page_insert(lua_State *L)
336
Page *p = check_page(L, 1)->page;
341
n = check_objno(L, 2, p, 1);
342
SObject *obj = check_object(L, 3);
343
TSelect select = check_select(L, 4);
344
int l = check_layer(L, 5, p);
345
p->insert(n, select, l, obj->obj->clone());
349
static int page_remove(lua_State *L)
351
Page *p = check_page(L, 1)->page;
352
int n = check_objno(L, 2, p);
357
static int page_replace(lua_State *L)
359
Page *p = check_page(L, 1)->page;
360
int n = check_objno(L, 2, p);
361
SObject *obj = check_object(L, 3);
362
p->replace(n, obj->obj->clone());
366
static int page_invalidateBBox(lua_State *L)
368
Page *p = check_page(L, 1)->page;
369
int n = check_objno(L, 2, p);
370
p->invalidateBBox(n);
374
static int page_transform(lua_State *L)
376
Page *p = check_page(L, 1)->page;
377
int n = check_objno(L, 2, p);
378
Matrix *m = check_matrix(L, 3);
383
static int page_distance(lua_State *L)
385
Page *p = check_page(L, 1)->page;
386
int n = check_objno(L, 2, p);
387
Vector *v = check_vector(L, 3);
388
double bound = luaL_checknumber(L, 4);
389
lua_pushnumber(L, p->distance(n, *v, bound));
393
static int page_setAttribute(lua_State *L)
395
Page *p = check_page(L, 1)->page;
396
int n = check_objno(L, 2, p);
397
Property prop = Property(luaL_checkoption(L, 3, NULL, property_names));
398
Attribute value = check_property(prop, L, 4);
399
Attribute stroke = Attribute::BLACK();
400
Attribute fill = Attribute::WHITE();
401
if (!lua_isnoneornil(L, 5))
402
stroke = check_color_attribute(L, 5);
403
if (!lua_isnoneornil(L, 6))
404
fill = check_color_attribute(L, 6);
405
lua_pushboolean(L, p->setAttribute(n, prop, value, stroke, fill));
409
static int page_primarySelection(lua_State *L)
411
Page *p = check_page(L, 1)->page;
412
int prim = p->primarySelection();
414
lua_pushnumber(L, prim + 1);
420
static int page_hasSelection(lua_State *L)
422
Page *p = check_page(L, 1)->page;
423
lua_pushboolean(L, p->hasSelection());
427
static int page_deselectAll(lua_State *L)
429
Page *p = check_page(L, 1)->page;
434
static int page_ensurePrimarySelection(lua_State *L)
436
Page *p = check_page(L, 1)->page;
437
p->ensurePrimarySelection();
441
static int page_textBox(lua_State *L)
443
Page *p = check_page(L, 1)->page;
444
Cascade *sheets = check_cascade(L, 2)->cascade;
445
push_rect(L, p->textBox(sheets));
449
static int page_titles(lua_State *L)
451
Page *p = check_page(L, 1)->page;
452
lua_createtable(L, 3, 0);
453
push_string(L, p->title());
454
lua_setfield(L, -2, "title");
455
if (!p->sectionUsesTitle(0)) {
456
push_string(L, p->section(0));
457
lua_setfield(L, -2, "section");
459
if (!p->sectionUsesTitle(1)) {
460
push_string(L, p->section(1));
461
lua_setfield(L, -2, "subsection");
466
static int page_setTitles(lua_State *L)
468
Page *p = check_page(L, 1)->page;
469
luaL_checktype(L, 2, LUA_TTABLE);
470
lua_getfield(L, 2, "title");
471
if (lua_isstring(L, -1))
472
p->setTitle(lua_tostring(L, -1));
473
lua_getfield(L, 2, "section");
474
if (lua_isstring(L, -1))
475
p->setSection(0, false, lua_tostring(L, -1));
477
p->setSection(0, true, "");
478
lua_getfield(L, 2, "subsection");
479
if (lua_isstring(L, -1))
480
p->setSection(1, false, lua_tostring(L, -1));
482
p->setSection(1, true, "");
483
lua_pop(L, 3); // title, section, subsection
487
// --------------------------------------------------------------------
489
static int page_countViews(lua_State *L)
491
Page *p = check_page(L, 1)->page;
492
lua_pushinteger(L, p->countViews());
496
static int page_effect(lua_State *L)
498
Page *p = check_page(L, 1)->page;
499
int n = check_viewno(L, 2, p);
500
push_string(L, p->effect(n).string());
504
static int page_setEffect(lua_State *L)
506
Page *p = check_page(L, 1)->page;
507
int n = check_viewno(L, 2, p);
508
const char *eff = luaL_checkstring(L, 3);
509
p->setEffect(n, Attribute(true, eff));
513
static int page_active(lua_State *L)
515
Page *p = check_page(L, 1)->page;
516
int n = check_viewno(L, 2, p);
517
push_string(L, p->active(n));
521
static int page_setActive(lua_State *L)
523
Page *p = check_page(L, 1)->page;
524
int n = check_viewno(L, 2, p);
525
const char *name = luaL_checkstring(L, 3);
526
p->setActive(n, name);
530
static int page_insertView(lua_State *L)
532
Page *p = check_page(L, 1)->page;
533
int n = check_viewno(L, 2, p, 1);
534
const char *name = luaL_checkstring(L, 3);
535
p->insertView(n, name);
539
static int page_removeView(lua_State *L)
541
Page *p = check_page(L, 1)->page;
542
int n = check_viewno(L, 2, p);
547
static int page_clearViews(lua_State *L)
549
Page *p = check_page(L, 1)->page;
554
// Either: view & layername
555
// Or: view & object index
556
static int page_visible(lua_State *L)
558
Page *p = check_page(L, 1)->page;
559
int vno = check_viewno(L, 2, p);
560
if (lua_type(L, 3) == LUA_TNUMBER) {
561
int objno = check_objno(L, 3, p);
562
lua_pushboolean(L, p->objectVisible(vno, objno));
564
int l = check_layer(L, 3, p);
565
lua_pushboolean(L, p->visible(vno, l));
570
static int page_setVisible(lua_State *L)
572
Page *p = check_page(L, 1)->page;
573
int vno = check_viewno(L, 2, p);
574
int l = check_layer(L, 3, p);
575
bool vis = lua_toboolean(L, 4);
576
p->setVisible(vno, p->layer(l), vis);
580
// --------------------------------------------------------------------
582
static int page_findedge(lua_State *L)
584
Page *p = check_page(L, 1)->page;
585
Vector pos = *check_vector(L, 2);
587
if (!snap.setEdge(pos, p))
589
push_vector(L, snap.iOrigin);
590
lua_pushnumber(L, snap.iDir);
594
// --------------------------------------------------------------------
596
static const struct luaL_Reg page_methods[] = {
597
{ "__index", page_index },
598
{ "__tostring", page_tostring },
599
{ "__gc", page_destructor },
600
{ "__len", page_len },
601
{ "clone", page_clone },
602
{ "objects", page_objects },
603
{ "countViews", page_countViews },
604
{ "countLayers", page_countLayers },
606
{ "layers", page_layers },
607
{ "isLocked", page_isLocked },
608
{ "hasSnapping", page_hasSnapping },
609
{ "setLocked", page_setLocked },
610
{ "setSnapping", page_setSnapping },
611
{ "renameLayer", page_renameLayer },
612
{ "addLayer", page_addLayer },
613
{ "removeLayer", page_removeLayer },
614
{ "select", page_select },
615
{ "setSelect", page_setSelect },
616
{ "layerOf", page_layerOf },
617
{ "setLayerOf", page_setLayerOf },
618
{ "effect", page_effect },
619
{ "setEffect", page_setEffect },
620
{ "active", page_active },
621
{ "setActive", page_setActive },
622
{ "insertView", page_insertView },
623
{ "removeView", page_removeView },
624
{ "clearViews", page_clearViews },
625
{ "visible", page_visible },
626
{ "setVisible", page_setVisible },
627
{ "bbox", page_bbox },
628
{ "insert", page_insert },
629
{ "remove", page_remove },
630
{ "replace", page_replace },
631
{ "invalidateBBox", page_invalidateBBox },
632
{ "transform", page_transform },
633
{ "distance", page_distance },
634
{ "setAttribute", page_setAttribute },
635
{ "primarySelection", page_primarySelection },
636
{ "hasSelection", page_hasSelection },
637
{ "deselectAll", page_deselectAll },
638
{ "ensurePrimarySelection", page_ensurePrimarySelection },
639
{ "findEdge", page_findedge },
640
{ "titles", page_titles },
641
{ "setTitles", page_setTitles },
642
{ "textBox", page_textBox },
646
// --------------------------------------------------------------------
648
int ipelua::open_ipepage(lua_State *L)
650
luaL_newmetatable(L, "Ipe.page");
651
luaL_register(L, 0, page_methods);
657
// --------------------------------------------------------------------