]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - stand/lua/drawer.lua
MFV r307315:
[FreeBSD/FreeBSD.git] / stand / lua / drawer.lua
1 --
2 -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
3 -- All rights reserved.
4 --
5 -- Redistribution and use in source and binary forms, with or without
6 -- modification, are permitted provided that the following conditions
7 -- are met:
8 -- 1. Redistributions of source code must retain the above copyright
9 --    notice, this list of conditions and the following disclaimer.
10 -- 2. Redistributions in binary form must reproduce the above copyright
11 --    notice, this list of conditions and the following disclaimer in the
12 --    documentation and/or other materials provided with the distribution.
13 --
14 -- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 -- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 -- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 -- ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 -- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 -- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 -- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 -- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 -- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 -- SUCH DAMAGE.
25 --
26 -- $FreeBSD$
27 --
28
29 local color = require("color");
30 local core = require("core");
31 local screen = require("screen");
32
33 local drawer = {};
34
35 local fbsd_logo;
36 local beastie_color;
37 local beastie;
38 local fbsd_logo_v;
39 local orb;
40 local none;
41
42 drawer.menu_name_handlers = {
43         -- Menu name handlers should take the menu being drawn and entry being
44         -- drawn as parameters, and return the name of the item.
45         -- This is designed so that everything, including menu separators, may
46         -- have their names derived differently. The default action for entry
47         -- types not specified here is to call and use entry.name().
48         [core.MENU_CAROUSEL_ENTRY] = function(drawing_menu, entry)
49                 local carid = entry.carousel_id;
50                 local caridx = menu.getCarouselIndex(carid);
51                 local choices = entry.items();
52
53                 if (#choices < caridx) then
54                         caridx = 1;
55                 end
56                 return entry.name(caridx, choices[caridx], choices);
57         end,
58 };
59
60 drawer.brand_position = {x = 2, y = 1};
61 drawer.logo_position = {x = 46, y = 1};
62 drawer.fbsd_logo_shift = {x = 5, y = 4};
63 drawer.orb_shift = {x = 2, y = 4};
64 drawer.none_shift = {x = 17, y = 0};
65 drawer.menu_position = {x = 6, y = 11};
66 drawer.box_pos_dim = {x = 3, y = 10, w = 41, h = 11};
67
68 fbsd_logo = {
69         "  ______               ____   _____ _____  ",
70         " |  ____|             |  _ \\ / ____|  __ \\ ",
71         " | |___ _ __ ___  ___ | |_) | (___ | |  | |",
72         " |  ___| '__/ _ \\/ _ \\|  _ < \\___ \\| |  | |",
73         " | |   | | |  __/  __/| |_) |____) | |__| |",
74         " | |   | | |    |    ||     |      |      |",
75         " |_|   |_|  \\___|\\___||____/|_____/|_____/ "
76 };
77
78 beastie_color = {
79         "               \027[31m,        ,",
80         "              /(        )`",
81         "              \\ \\___   / |",
82         "              /- \027[37m_\027[31m  `-/  '",
83         "             (\027[37m/\\/ \\\027[31m \\   /\\",
84         "             \027[37m/ /   |\027[31m `    \\",
85         "             \027[34mO O   \027[37m) \027[31m/    |",
86         "             \027[37m`-^--'\027[31m`<     '",
87         "            (_.)  _  )   /",
88         "             `.___/`    /",
89         "               `-----' /",
90         "  \027[33m<----.\027[31m     __ / __   \\",
91         "  \027[33m<----|====\027[31mO)))\027[33m==\027[31m) \\) /\027[33m====|",
92         "  \027[33m<----'\027[31m    `--' `.__,' \\",
93         "               |        |",
94         "                \\       /       /\\",
95         "           \027[36m______\027[31m( (_  / \\______/",
96         "         \027[36m,'  ,-----'   |",
97         "         `--{__________)\027[37m"
98 };
99
100 beastie = {
101         "               ,        ,",
102         "              /(        )`",
103         "              \\ \\___   / |",
104         "              /- _  `-/  '",
105         "             (/\\/ \\ \\   /\\",
106         "             / /   | `    \\",
107         "             O O   ) /    |",
108         "             `-^--'`<     '",
109         "            (_.)  _  )   /",
110         "             `.___/`    /",
111         "               `-----' /",
112         "  <----.     __ / __   \\",
113         "  <----|====O)))==) \\) /====|",
114         "  <----'    `--' `.__,' \\",
115         "               |        |",
116         "                \\       /       /\\",
117         "           ______( (_  / \\______/",
118         "         ,'  ,-----'   |",
119         "         `--{__________)"
120 };
121
122 fbsd_logo_v = {
123         "  ______",
124         " |  ____| __ ___  ___ ",
125         " | |__ | '__/ _ \\/ _ \\",
126         " |  __|| | |  __/  __/",
127         " | |   | | |    |    |",
128         " |_|   |_|  \\___|\\___|",
129         "  ____   _____ _____",
130         " |  _ \\ / ____|  __ \\",
131         " | |_) | (___ | |  | |",
132         " |  _ < \\___ \\| |  | |",
133         " | |_) |____) | |__| |",
134         " |     |      |      |",
135         " |____/|_____/|_____/"
136 };
137
138 orb_color = {
139         "  \027[31m```                        \027[31;1m`\027[31m",
140         " s` `.....---...\027[31;1m....--.```   -/\027[31m",
141         " +o   .--`         \027[31;1m/y:`      +.\027[31m",
142         "  yo`:.            \027[31;1m:o      `+-\027[31m",
143         "   y/               \027[31;1m-/`   -o/\027[31m",
144         "  .-                  \027[31;1m::/sy+:.\027[31m",
145         "  /                     \027[31;1m`--  /\027[31m",
146         " `:                          \027[31;1m:`\027[31m",
147         " `:                          \027[31;1m:`\027[31m",
148         "  /                          \027[31;1m/\027[31m",
149         "  .-                        \027[31;1m-.\027[31m",
150         "   --                      \027[31;1m-.\027[31m",
151         "    `:`                  \027[31;1m`:`",
152         "      \027[31;1m.--             `--.",
153         "         .---.....----.\027[37m"
154 };
155
156 orb = {
157         "  ```                        `",
158         " s` `.....---.......--.```   -/",
159         " +o   .--`         /y:`      +.",
160         "  yo`:.            :o      `+-",
161         "   y/               -/`   -o/",
162         "  .-                  ::/sy+:.",
163         "  /                     `--  /",
164         " `:                          :`",
165         " `:                          :`",
166         "  /                          /",
167         "  .-                        -.",
168         "   --                      -.",
169         "    `:`                  `:`",
170         "      .--             `--.",
171         "         .---.....----."
172 };
173
174 none = {""};
175
176 function drawer.drawscreen(menu_opts)
177         -- drawlogo() must go first.
178         -- it determines the positions of other elements
179         drawer.drawlogo();
180         drawer.drawbrand();
181         drawer.drawbox();
182         return drawer.drawmenu(menu_opts);
183 end
184
185 function menu_entry_name(drawing_menu, entry)
186         local name_handler = drawer.menu_name_handlers[entry.entry_type];
187
188         if (name_handler ~= nil) then
189                 return name_handler(drawing_menu, entry);
190         end
191         return entry.name();
192 end
193
194 function drawer.drawmenu(m)
195         x = drawer.menu_position.x;
196         y = drawer.menu_position.y;
197
198         -- print the menu and build the alias table
199         local alias_table = {};
200         local entry_num = 0;
201         local menu_entries = m.entries;
202         if (type(menu_entries) == "function") then
203                 menu_entries = menu_entries();
204         end
205         for line_num, e in ipairs(menu_entries) do
206                 -- Allow menu items to be conditionally visible by specifying
207                 -- a visible function.
208                 if (e.visible ~= nil) and (not e.visible()) then
209                         goto continue;
210                 end
211                 if (e.entry_type ~= core.MENU_SEPARATOR) then
212                         entry_num = entry_num + 1;
213                         screen.setcursor(x, y + line_num);
214
215                         print(entry_num .. ". " .. menu_entry_name(m, e));
216
217                         -- fill the alias table
218                         alias_table[tostring(entry_num)] = e;
219                         if (e.alias ~= nil) then
220                                 for n, a in ipairs(e.alias) do
221                                         alias_table[a] = e;
222                                 end
223                         end
224                 else
225                         screen.setcursor(x, y + line_num);
226                         print(menu_entry_name(m, e));
227                 end
228                 ::continue::
229         end
230         return alias_table;
231 end
232
233
234 function drawer.drawbox()
235         x = drawer.box_pos_dim.x;
236         y = drawer.box_pos_dim.y;
237         w = drawer.box_pos_dim.w;
238         h = drawer.box_pos_dim.h;
239
240         local hl = string.char(0xCD);
241         local vl = string.char(0xBA);
242
243         local tl = string.char(0xC9);
244         local bl = string.char(0xC8);
245         local tr = string.char(0xBB);
246         local br = string.char(0xBC);
247
248         screen.setcursor(x, y); print(tl);
249         screen.setcursor(x, y+h); print(bl);
250         screen.setcursor(x+w, y); print(tr);
251         screen.setcursor(x+w, y+h); print(br);
252
253         for i = 1, w-1 do
254                 screen.setcursor(x+i, y);
255                 print(hl);
256                 screen.setcursor(x+i, y+h);
257                 print(hl);
258         end
259
260         for i = 1, h-1 do
261                 screen.setcursor(x, y+i);
262                 print(vl);
263                 screen.setcursor(x+w, y+i);
264                 print(vl);
265         end
266
267         screen.setcursor(x+(w/2)-9, y);
268         print("Welcome to FreeBSD");
269 end
270
271 function drawer.draw(x, y, logo)
272         for i = 1, #logo do
273                 screen.setcursor(x, y + i);
274                 print(logo[i]);
275         end
276 end
277
278 function drawer.drawbrand()
279         local x = tonumber(loader.getenv("loader_brand_x")) or
280             drawer.brand_position.x;
281         local y = tonumber(loader.getenv("loader_brand_y")) or
282             drawer.brand_position.y;
283
284         local logo = load("return " .. tostring(loader.getenv("loader_brand")))() or
285             fbsd_logo;
286         drawer.draw(x, y, logo);
287 end
288
289 function drawer.drawlogo()
290         local x = tonumber(loader.getenv("loader_logo_x")) or
291             drawer.logo_position.x;
292         local y = tonumber(loader.getenv("loader_logo_y")) or
293             drawer.logo_position.y;
294
295         local logo = loader.getenv("loader_logo");
296         local s = {x = 0, y = 0};
297         local colored = color.isEnabled();
298
299         if (logo == "beastie") then
300                 if (colored) then
301                         logo = beastie_color;
302                 end
303         elseif (logo == "beastiebw") then
304                 logo = beastie;
305         elseif (logo == "fbsdbw") then
306                 logo = fbsd_logo_v;
307                 s = drawer.fbsd_logo_shift;
308         elseif (logo == "orb") then
309                 if (colored) then
310                         logo = orb_color;
311                 end
312                 s = drawer.orb_shift;
313         elseif (logo == "orbbw") then
314                 logo = orb;
315                 s = drawer.orb_shift;
316         elseif (logo == "tribute") then
317                 logo = fbsd_logo;
318         elseif (logo == "tributebw") then
319                 logo = fbsd_logo;
320         elseif (logo == "none") then
321                 --centre brand and text if no logo
322                 drawer.brand_position.x = drawer.brand_position.x + drawer.none_shift.x;
323                 drawer.brand_position.y = drawer.brand_position.y + drawer.none_shift.y;
324                 drawer.menu_position.x = drawer.menu_position.x + drawer.none_shift.x;
325                 drawer.menu_position.y = drawer.menu_position.y + drawer.none_shift.y;
326                 drawer.box_pos_dim.x = drawer.box_pos_dim.x + drawer.none_shift.x;
327                 drawer.box_pos_dim.y = drawer.box_pos_dim.y + drawer.none_shift.y;
328                 --prevent redraws from moving menu further
329                 drawer.none_shift.x = 0;
330                 drawer.none_shift.y = 0;
331                 logo = none;
332         end
333         if (not logo) then
334                 if (colored) then
335                         logo = orb_color;
336                 else
337                         logo = orb;
338                 end
339         end
340         drawer.draw(x + s.x, y + s.y, logo);
341 end
342
343 return drawer;