xref: /freebsd/stand/lua/drawer.lua (revision 24a1bd54dc7d8deb3b354f100d36f7b0f43cb610)
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
29local drawer = {};
30
31local color = require("color");
32local core = require("core");
33local screen = require("screen");
34
35drawer.brand_position = {x = 2, y = 1};
36drawer.fbsd_logo = {
37	"  ______               ____   _____ _____  ",
38	" |  ____|             |  _ \\ / ____|  __ \\ ",
39	" | |___ _ __ ___  ___ | |_) | (___ | |  | |",
40	" |  ___| '__/ _ \\/ _ \\|  _ < \\___ \\| |  | |",
41	" | |   | | |  __/  __/| |_) |____) | |__| |",
42	" | |   | | |    |    ||     |      |      |",
43	" |_|   |_|  \\___|\\___||____/|_____/|_____/ "
44};
45
46drawer.logo_position = {x = 46, y = 1};
47drawer.beastie_color = {
48	"               \027[31m,        ,",
49	"              /(        )`",
50	"              \\ \\___   / |",
51	"              /- \027[37m_\027[31m  `-/  '",
52	"             (\027[37m/\\/ \\\027[31m \\   /\\",
53	"             \027[37m/ /   |\027[31m `    \\",
54	"             \027[34mO O   \027[37m) \027[31m/    |",
55	"             \027[37m`-^--'\027[31m`<     '",
56	"            (_.)  _  )   /",
57	"             `.___/`    /",
58	"               `-----' /",
59	"  \027[33m<----.\027[31m     __ / __   \\",
60	"  \027[33m<----|====\027[31mO)))\027[33m==\027[31m) \\) /\027[33m====|",
61	"  \027[33m<----'\027[31m    `--' `.__,' \\",
62	"               |        |",
63	"                \\       /       /\\",
64	"           \027[36m______\027[31m( (_  / \\______/",
65	"         \027[36m,'  ,-----'   |",
66	"         `--{__________)\027[37m"
67};
68
69drawer.beastie = {
70	"               ,        ,",
71	"              /(        )`",
72	"              \\ \\___   / |",
73	"              /- _  `-/  '",
74	"             (/\\/ \\ \\   /\\",
75	"             / /   | `    \\",
76	"             O O   ) /    |",
77	"             `-^--'`<     '",
78	"            (_.)  _  )   /",
79	"             `.___/`    /",
80	"               `-----' /",
81	"  <----.     __ / __   \\",
82	"  <----|====O)))==) \\) /====|",
83	"  <----'    `--' `.__,' \\",
84	"               |        |",
85	"                \\       /       /\\",
86	"           ______( (_  / \\______/",
87	"         ,'  ,-----'   |",
88	"         `--{__________)"
89};
90
91drawer.fbsd_logo_shift = {x = 5, y = 4};
92drawer.fbsd_logo_v = {
93	"  ______",
94	" |  ____| __ ___  ___ ",
95	" | |__ | '__/ _ \\/ _ \\",
96	" |  __|| | |  __/  __/",
97	" | |   | | |    |    |",
98	" |_|   |_|  \\___|\\___|",
99	"  ____   _____ _____",
100	" |  _ \\ / ____|  __ \\",
101	" | |_) | (___ | |  | |",
102	" |  _ < \\___ \\| |  | |",
103	" | |_) |____) | |__| |",
104	" |     |      |      |",
105	" |____/|_____/|_____/"
106};
107
108drawer.orb_shift = {x = 2, y = 4};
109drawer.orb_color = {
110	"  \027[31m```                        \027[31;1m`\027[31m",
111	" s` `.....---...\027[31;1m....--.```   -/\027[31m",
112	" +o   .--`         \027[31;1m/y:`      +.\027[31m",
113	"  yo`:.            \027[31;1m:o      `+-\027[31m",
114	"   y/               \027[31;1m-/`   -o/\027[31m",
115	"  .-                  \027[31;1m::/sy+:.\027[31m",
116	"  /                     \027[31;1m`--  /\027[31m",
117	" `:                          \027[31;1m:`\027[31m",
118	" `:                          \027[31;1m:`\027[31m",
119	"  /                          \027[31;1m/\027[31m",
120	"  .-                        \027[31;1m-.\027[31m",
121	"   --                      \027[31;1m-.\027[31m",
122	"    `:`                  \027[31;1m`:`",
123	"      \027[31;1m.--             `--.",
124	"         .---.....----.\027[37m"
125};
126
127drawer.orb = {
128	"  ```                        `",
129	" s` `.....---.......--.```   -/",
130	" +o   .--`         /y:`      +.",
131	"  yo`:.            :o      `+-",
132	"   y/               -/`   -o/",
133	"  .-                  ::/sy+:.",
134	"  /                     `--  /",
135	" `:                          :`",
136	" `:                          :`",
137	"  /                          /",
138	"  .-                        -.",
139	"   --                      -.",
140	"    `:`                  `:`",
141	"      .--             `--.",
142	"         .---.....----."
143};
144
145drawer.none = {""};
146
147drawer.none_shift = {x = 17, y = 0};
148
149drawer.menu_position = {x = 6, y = 11};
150
151drawer.box_pos_dim = {x = 3, y = 10, w = 41, h = 11};
152
153function drawer.drawscreen(menu_opts)
154	-- drawlogo() must go first.
155	-- it determines the positions of other elements
156	drawer.drawlogo();
157        drawer.drawbrand();
158        drawer.drawbox();
159	return drawer.drawmenu(menu_opts);
160end
161
162function drawer.drawmenu(m)
163	x = drawer.menu_position.x;
164	y = drawer.menu_position.y;
165
166	-- print the menu and build the alias table
167	local alias_table = {};
168	local entry_num = 0;
169	for line_num, e in ipairs(m) do
170		if (e.entry_type ~= core.MENU_SEPARATOR) then
171			entry_num = entry_num + 1;
172			screen.setcursor(x, y + line_num);
173			local name = "";
174
175			if (e.entry_type == core.MENU_CAROUSEL_ENTRY) then
176				local carid = e.carousel_id;
177				local caridx = menu.getCarouselIndex(carid);
178				local choices = e.items();
179
180				if (#choices < caridx) then
181					caridx = 1;
182				end
183				name = e.name(caridx, choices[caridx], choices);
184			else
185				name = e.name();
186			end
187			print(entry_num .. ". "..name);
188
189			-- fill the alias table
190			alias_table[tostring(entry_num)] = e;
191			if (e.alias ~= nil) then
192				for n, a in ipairs(e.alias) do
193					alias_table[a] = e;
194				end
195			end
196		else
197			screen.setcursor(x, y + line_num);
198			print(e.name());
199		end
200	end
201	return alias_table;
202end
203
204
205function drawer.drawbox()
206	x = drawer.box_pos_dim.x;
207	y = drawer.box_pos_dim.y;
208	w = drawer.box_pos_dim.w;
209	h = drawer.box_pos_dim.h;
210
211	local hl = string.char(0xCD);
212	local vl = string.char(0xBA);
213
214	local tl = string.char(0xC9);
215	local bl = string.char(0xC8);
216	local tr = string.char(0xBB);
217	local br = string.char(0xBC);
218
219	screen.setcursor(x, y); print(tl);
220	screen.setcursor(x, y+h); print(bl);
221	screen.setcursor(x+w, y); print(tr);
222	screen.setcursor(x+w, y+h); print(br);
223
224	for i = 1, w-1 do
225		screen.setcursor(x+i, y);
226		print(hl);
227		screen.setcursor(x+i, y+h);
228		print(hl);
229	end
230
231	for i = 1, h-1 do
232		screen.setcursor(x, y+i);
233		print(vl);
234		screen.setcursor(x+w, y+i);
235		print(vl);
236	end
237
238	screen.setcursor(x+(w/2)-9, y);
239	print("Welcome to FreeBSD");
240end
241
242function drawer.draw(x, y, logo)
243	for i = 1, #logo do
244		screen.setcursor(x, y + i);
245		print(logo[i]);
246	end
247end
248
249function drawer.drawbrand()
250	local x = tonumber(loader.getenv("loader_brand_x")) or
251	    drawer.brand_position.x;
252	local y = tonumber(loader.getenv("loader_brand_y")) or
253	    drawer.brand_position.y;
254
255	local logo = load("return " .. tostring(loader.getenv("loader_brand")))() or
256	    drawer.fbsd_logo;
257	drawer.draw(x, y, logo);
258end
259
260function drawer.drawlogo()
261	local x = tonumber(loader.getenv("loader_logo_x")) or
262	    drawer.logo_position.x;
263	local y = tonumber(loader.getenv("loader_logo_y")) or
264	    drawer.logo_position.y;
265
266	local logo = loader.getenv("loader_logo");
267	local s = {x = 0, y = 0};
268	local colored = color.isEnabled();
269
270	if (logo == "beastie") then
271		if (colored) then
272			logo = drawer.beastie_color;
273		end
274	elseif (logo == "beastiebw") then
275		logo = drawer.beastie;
276	elseif (logo == "fbsdbw") then
277		logo = drawer.fbsd_logo_v;
278		s = drawer.fbsd_logo_shift;
279	elseif (logo == "orb") then
280		if (colored) then
281			logo = drawer.orb_color;
282		end
283		s = drawer.orb_shift;
284	elseif (logo == "orbbw") then
285		logo = drawer.orb;
286		s = drawer.orb_shift;
287	elseif (logo == "tribute") then
288		logo = drawer.fbsd_logo;
289	elseif (logo == "tributebw") then
290		logo = drawer.fbsd_logo;
291	elseif (logo == "none") then
292		--centre brand and text if no logo
293		drawer.brand_position.x = drawer.brand_position.x + drawer.none_shift.x;
294		drawer.brand_position.y = drawer.brand_position.y + drawer.none_shift.y;
295		drawer.menu_position.x = drawer.menu_position.x + drawer.none_shift.x;
296		drawer.menu_position.y = drawer.menu_position.y + drawer.none_shift.y;
297		drawer.box_pos_dim.x = drawer.box_pos_dim.x + drawer.none_shift.x;
298		drawer.box_pos_dim.y = drawer.box_pos_dim.y + drawer.none_shift.y;
299		--prevent redraws from moving menu further
300		drawer.none_shift.x = 0;
301		drawer.none_shift.y = 0;
302		logo = drawer.none;
303	end
304	if (not logo) then
305		if (colored) then
306			logo = drawer.orb_color;
307		else
308			logo = drawer.orb;
309		end
310	end
311	drawer.draw(x + s.x, y + s.y, logo);
312end
313
314return drawer;
315