1// This file is part of SmallBASIC
2//
3// Window object
4//
5// This program is distributed under the terms of the GPL v2.0 or later
6// Download the GNU Public License (GPL) from www.gnu.org
7//
8// Copyright(C) 2007-2014 Chris Warren-Smith.
9
10#include "common/sys.h"
11#include "common/pproc.h"
12#include "lib/maapi.h"
13#include "ui/system.h"
14#include "ui/theme.h"
15
16extern System *g_system;
17
18#define WINDOW_SCREEN1 "graphicsScreen1"
19#define WINDOW_SCREEN2 "graphicsScreen2"
20#define WINDOW_SCREEN3 "textScreen"
21#define WINDOW_ALERT "alert"
22#define WINDOW_ASK "ask"
23#define WINDOW_ASK_RTN "answer"
24#define WINDOW_MENU "menu"
25#define WINDOW_MESSAGE "message"
26#define WINDOW_SHOWKPAD "showKeypad"
27#define WINDOW_HIDEKPAD "hideKeypad"
28#define WINDOW_INSET "insetTextScreen"
29#define WINDOW_SETFONT "setFont"
30#define WINDOW_SETSIZE "setSize"
31#define WINDOW_THEME "theme"
32
33// returns the next set of string variable arguments as a String list
34StringList *get_items() {
35 var_t arg;
36 bool done = false;
37 StringList *items = new StringList();
38 do {
39 switch (code_peek()) {
40 case kwTYPE_LINE:
41 case kwTYPE_EOC:
42 case kwTYPE_LEVEL_END:
43 done = true;
44 break;
45 case kwTYPE_SEP:
46 code_skipnext();
47 if (code_getnext() != ',') {
48 err_missing_comma();
49 }
50 break;
51 default:
52 v_init(&arg);
53 eval(&arg);
54 if (arg.type == V_STR && !prog_error) {
55 items->add(new String(arg.v.p.ptr));
56 }
57 v_free(&arg);
58 break;
59 }
60 } while (!done && !prog_error);
61 return items;
62}
63
64void cmd_window_select_screen1(var_s *self, var_s *) {
65 g_system->getOutput()->selectScreen(USER_SCREEN1);
66}
67
68void cmd_window_select_screen2(var_s *self, var_s *) {
69 g_system->getOutput()->selectScreen(USER_SCREEN2);
70}
71
72void cmd_window_select_screen3(var_s *self, var_s *) {
73 g_system->getOutput()->selectScreen(TEXT_SCREEN);
74}
75
76void cmd_window_show_keypad(var_s *self, var_s *) {
77 maShowVirtualKeyboard();
78}
79
80void cmd_window_hide_keypad(var_s *self, var_s *) {
81 maHideVirtualKeyboard();
82}
83
84void cmd_window_inset(var_s *self, var_s *) {
85 var_int_t x, y, w, h;
86 par_massget("IIII", &x, &y, &w, &h);
87 if (!prog_error) {
88 if (x < 0 || x > 100 ||
89 y < 0 || y > 100 ||
90 w < 1 || x + w > 100 ||
91 h < 1 || y + h > 100) {
92 err_out_of_range();
93 } else {
94 g_system->getOutput()->insetTextScreen(x, y, w, h);
95 }
96 }
97}
98
99void cmd_window_set_font(var_s *self, var_s *) {
100 var_num_t size;
101 var_int_t bold, italic;
102 char *unit = NULL;
103 par_massget("FSII", &size, &unit, &bold, &italic);
104 if (unit != NULL && strcmp(unit, "em") == 0) {
105 size *= g_system->getOutput()->getFontSize();
106 }
107 g_system->getOutput()->setFont(size, bold, italic);
108 pfree(unit);
109}
110
111void cmd_window_set_size(var_s *self, var_s *) {
112 var_int_t width, height;
113 par_massget("II", &width, &height);
114 g_system->setWindowSize(width, height);
115}
116
117void cmd_window_get_theme(var_s *, var_s *retval) {
118 if (retval != nullptr) {
119 EditTheme theme;
120 theme.setId(g_themeId);
121 v_init(retval);
122 map_init(retval);
123 map_set_int(retval, "background", -theme._background);
124 map_set_int(retval, "text1", -theme._color);
125 map_set_int(retval, "text2", -theme._syntax_text);
126 map_set_int(retval, "text3", -theme._syntax_comments);
127 map_set_int(retval, "text4", -theme._syntax_command);
128 map_set_int(retval, "text5", -theme._syntax_statement);
129 map_set_int(retval, "text6", -theme._syntax_digit);
130 }
131}
132
133void cmd_window_alert(var_s *self, var_s *) {
134 StringList *items = get_items();
135 if (!prog_error && items->size() > 0) {
136 const char *message = items->size() > 0 ? (*items)[0]->c_str() : "";
137 const char *title = items->size() > 1 ? (*items)[1]->c_str() : "";
138 g_system->alert(title, message);
139 }
140 delete items;
141}
142
143void cmd_window_ask(var_s *self, var_s *retval) {
144 StringList *items = get_items();
145 if (!prog_error && items->size() > 0) {
146 const char *message = items->size() > 0 ? (*items)[0]->c_str() : "";
147 const char *title = items->size() > 1 ? (*items)[1]->c_str() : "";
148 int result = g_system->ask(title, message, false);
149 map_set_int(self, WINDOW_ASK_RTN, result);
150 if (retval != nullptr) {
151 v_setint(retval, result);
152 }
153 }
154 delete items;
155}
156
157void cmd_window_menu(var_s *self, var_s *) {
158 StringList *items = get_items();
159 if (!prog_error && items->size() > 0) {
160 g_system->optionsBox(items);
161 }
162 delete items;
163}
164
165void cmd_window_message(var_s *self, var_s *) {
166 var_t arg;
167 v_init(&arg);
168 eval(&arg);
169 if (arg.type == V_STR && !prog_error) {
170 g_system->getOutput()->setStatus(arg.v.p.ptr);
171 }
172 v_free(&arg);
173}
174
175extern "C" void v_create_window(var_p_t var) {
176 map_init(var);
177 v_create_func(var, WINDOW_SCREEN1, cmd_window_select_screen1);
178 v_create_func(var, WINDOW_SCREEN2, cmd_window_select_screen2);
179 v_create_func(var, WINDOW_SCREEN3, cmd_window_select_screen3);
180 v_create_func(var, WINDOW_ALERT, cmd_window_alert);
181 v_create_func(var, WINDOW_ASK, cmd_window_ask);
182 v_create_func(var, WINDOW_MESSAGE, cmd_window_message);
183 v_create_func(var, WINDOW_MENU, cmd_window_menu);
184 v_create_func(var, WINDOW_SHOWKPAD, cmd_window_show_keypad);
185 v_create_func(var, WINDOW_HIDEKPAD, cmd_window_hide_keypad);
186 v_create_func(var, WINDOW_INSET, cmd_window_inset);
187 v_create_func(var, WINDOW_SETFONT, cmd_window_set_font);
188 v_create_func(var, WINDOW_SETSIZE, cmd_window_set_size);
189 v_create_func(var, WINDOW_THEME, cmd_window_get_theme);
190}
191
192extern "C" void dev_show_page() {
193 byte code = code_peek();
194 switch (code) {
195 case kwTYPE_LINE:
196 case kwTYPE_EOC:
197 case kwTYPE_SEP:
198 break;
199 default:
200 g_system->getOutput()->setAutoflush(par_getint());
201 break;
202 }
203 g_system->getOutput()->redraw();
204}
205