xref: /freebsd/stand/lua/drawer.lua (revision 74709ed038c5cdffc65586a83a160ddd07b27515)
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		-- Allow menu items to be conditionally visible by specifying
171		-- a visible function.
172		if (e.visible ~= nil) and (not e.visible()) then
173			goto continue;
174		end
175		if (e.entry_type ~= core.MENU_SEPARATOR) then
176			entry_num = entry_num + 1;
177			screen.setcursor(x, y + line_num);
178			local name = "";
179
180			if (e.entry_type == core.MENU_CAROUSEL_ENTRY) then
181				local carid = e.carousel_id;
182				local caridx = menu.getCarouselIndex(carid);
183				local choices = e.items();
184
185				if (#choices < caridx) then
186					caridx = 1;
187				end
188				name = e.name(caridx, choices[caridx], choices);
189			else
190				name = e.name();
191			end
192			print(entry_num .. ". "..name);
193
194			-- fill the alias table
195			alias_table[tostring(entry_num)] = e;
196			if (e.alias ~= nil) then
197				for n, a in ipairs(e.alias) do
198					alias_table[a] = e;
199				end
200			end
201		else
202			screen.setcursor(x, y + line_num);
203			print(e.name());
204		end
205		::continue::
206	end
207	return alias_table;
208end
209
210
211function drawer.drawbox()
212	x = drawer.box_pos_dim.x;
213	y = drawer.box_pos_dim.y;
214	w = drawer.box_pos_dim.w;
215	h = drawer.box_pos_dim.h;
216
217	local hl = string.char(0xCD);
218	local vl = string.char(0xBA);
219
220	local tl = string.char(0xC9);
221	local bl = string.char(0xC8);
222	local tr = string.char(0xBB);
223	local br = string.char(0xBC);
224
225	screen.setcursor(x, y); print(tl);
226	screen.setcursor(x, y+h); print(bl);
227	screen.setcursor(x+w, y); print(tr);
228	screen.setcursor(x+w, y+h); print(br);
229
230	for i = 1, w-1 do
231		screen.setcursor(x+i, y);
232		print(hl);
233		screen.setcursor(x+i, y+h);
234		print(hl);
235	end
236
237	for i = 1, h-1 do
238		screen.setcursor(x, y+i);
239		print(vl);
240		screen.setcursor(x+w, y+i);
241		print(vl);
242	end
243
244	screen.setcursor(x+(w/2)-9, y);
245	print("Welcome to FreeBSD");
246end
247
248function drawer.draw(x, y, logo)
249	for i = 1, #logo do
250		screen.setcursor(x, y + i);
251		print(logo[i]);
252	end
253end
254
255function drawer.drawbrand()
256	local x = tonumber(loader.getenv("loader_brand_x")) or
257	    drawer.brand_position.x;
258	local y = tonumber(loader.getenv("loader_brand_y")) or
259	    drawer.brand_position.y;
260
261	local logo = load("return " .. tostring(loader.getenv("loader_brand")))() or
262	    drawer.fbsd_logo;
263	drawer.draw(x, y, logo);
264end
265
266function drawer.drawlogo()
267	local x = tonumber(loader.getenv("loader_logo_x")) or
268	    drawer.logo_position.x;
269	local y = tonumber(loader.getenv("loader_logo_y")) or
270	    drawer.logo_position.y;
271
272	local logo = loader.getenv("loader_logo");
273	local s = {x = 0, y = 0};
274	local colored = color.isEnabled();
275
276	if (logo == "beastie") then
277		if (colored) then
278			logo = drawer.beastie_color;
279		end
280	elseif (logo == "beastiebw") then
281		logo = drawer.beastie;
282	elseif (logo == "fbsdbw") then
283		logo = drawer.fbsd_logo_v;
284		s = drawer.fbsd_logo_shift;
285	elseif (logo == "orb") then
286		if (colored) then
287			logo = drawer.orb_color;
288		end
289		s = drawer.orb_shift;
290	elseif (logo == "orbbw") then
291		logo = drawer.orb;
292		s = drawer.orb_shift;
293	elseif (logo == "tribute") then
294		logo = drawer.fbsd_logo;
295	elseif (logo == "tributebw") then
296		logo = drawer.fbsd_logo;
297	elseif (logo == "none") then
298		--centre brand and text if no logo
299		drawer.brand_position.x = drawer.brand_position.x + drawer.none_shift.x;
300		drawer.brand_position.y = drawer.brand_position.y + drawer.none_shift.y;
301		drawer.menu_position.x = drawer.menu_position.x + drawer.none_shift.x;
302		drawer.menu_position.y = drawer.menu_position.y + drawer.none_shift.y;
303		drawer.box_pos_dim.x = drawer.box_pos_dim.x + drawer.none_shift.x;
304		drawer.box_pos_dim.y = drawer.box_pos_dim.y + drawer.none_shift.y;
305		--prevent redraws from moving menu further
306		drawer.none_shift.x = 0;
307		drawer.none_shift.y = 0;
308		logo = drawer.none;
309	end
310	if (not logo) then
311		if (colored) then
312			logo = drawer.orb_color;
313		else
314			logo = drawer.orb;
315		end
316	end
317	drawer.draw(x + s.x, y + s.y, logo);
318end
319
320return drawer;
321