xref: /freebsd-14.2/stand/lua/drawer.lua (revision ab4a4d40)
1--
2-- Copyright (c) 2015 Pedro Souza <[email protected]>
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"));
251	local y = tonumber(loader.getenv("loader_brand_y"));
252
253	if not x then
254		x = drawer.brand_position.x;
255	end
256	if not y then
257		y = drawer.brand_position.y;
258	end
259
260	local logo = load("return " .. tostring(loader.getenv("loader_brand")))();
261	if not logo then
262		logo = drawer.fbsd_logo;
263	end
264	drawer.draw(x, y, logo);
265end
266
267function drawer.drawlogo()
268	local x = tonumber(loader.getenv("loader_logo_x"));
269	local y = tonumber(loader.getenv("loader_logo_y"));
270
271	if not x then
272		x = drawer.logo_position.x;
273	end
274	if not y then
275		y = drawer.logo_position.y;
276	end
277
278	local logo = loader.getenv("loader_logo");
279	local s = {x = 0, y = 0};
280	local colored = color.isEnabled();
281
282	if logo == "beastie" then
283		if colored then
284			logo = drawer.beastie_color;
285		end
286	elseif logo == "beastiebw" then
287		logo = drawer.beastie;
288	elseif logo == "fbsdbw" then
289		logo = drawer.fbsd_logo_v;
290		s = drawer.fbsd_logo_shift;
291	elseif logo == "orb" then
292		if colored then
293			logo = drawer.orb_color;
294		end
295		s = drawer.orb_shift;
296	elseif logo == "orbbw" then
297		logo = drawer.orb;
298		s = drawer.orb_shift;
299	elseif logo == "tribute" then
300		logo = drawer.fbsd_logo;
301	elseif logo == "tributebw" then
302		logo = drawer.fbsd_logo;
303	elseif logo == "none" then
304		--centre brand and text if no logo
305		drawer.brand_position.x = drawer.brand_position.x + drawer.none_shift.x;
306		drawer.brand_position.y = drawer.brand_position.y + drawer.none_shift.y;
307		drawer.menu_position.x = drawer.menu_position.x + drawer.none_shift.x;
308		drawer.menu_position.y = drawer.menu_position.y + drawer.none_shift.y;
309		drawer.box_pos_dim.x = drawer.box_pos_dim.x + drawer.none_shift.x;
310		drawer.box_pos_dim.y = drawer.box_pos_dim.y + drawer.none_shift.y;
311		--prevent redraws from moving menu further
312		drawer.none_shift.x = 0;
313		drawer.none_shift.y = 0;
314		logo = drawer.none;
315	end
316	if not logo then
317		if colored then
318			logo = drawer.orb_color;
319		else
320			logo = drawer.orb;
321		end
322	end
323	drawer.draw(x + s.x, y + s.y, logo);
324end
325
326return drawer
327