mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 10:38:09 +08:00 
			
		
		
		
	Add webassembly support
This commit is contained in:
		| @@ -1,3 +1,14 @@ | ||||
| add_subdirectory(component) | ||||
| add_subdirectory(dom) | ||||
| add_subdirectory(util) | ||||
|  | ||||
| if (EMSCRIPTEN) | ||||
|   foreach(file | ||||
|       "index.html" | ||||
|       "run_webassembly.sh") | ||||
|     configure_file( | ||||
|       ${CMAKE_CURRENT_SOURCE_DIR}/${file} | ||||
|       ${CMAKE_CURRENT_BINARY_DIR}/${file} | ||||
|     ) | ||||
|   endforeach(file) | ||||
| endif() | ||||
|   | ||||
| @@ -28,7 +28,7 @@ int main(int argc, const char* argv[]) { | ||||
|       }); | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|   std::cout << screen.ToString() << std::endl; | ||||
|   screen.Print(); | ||||
| } | ||||
|  | ||||
| // Copyright 2020 Arthur Sonzogni. All rights reserved. | ||||
|   | ||||
| @@ -126,7 +126,7 @@ int main(int argc, const char* argv[]) { | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -30,7 +30,7 @@ int main(int argc, const char* argv[]) { | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -26,7 +26,7 @@ int main(int argc, const char* argv[]) { | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -45,7 +45,7 @@ int main(int argc, const char* argv[]) { | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -17,7 +17,7 @@ int main(int argc, const char* argv[]) { | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,8 @@ int main(int argc, const char* argv[]) { | ||||
|     }); | ||||
|     auto screen = Screen(100, 1); | ||||
|     Render(screen, document); | ||||
|     std::cout << reset_position << screen.ToString() << std::flush; | ||||
|     std::cout << reset_position; | ||||
|     screen.Print(); | ||||
|     reset_position = screen.ResetPosition(); | ||||
|  | ||||
|     std::this_thread::sleep_for(0.01s); | ||||
|   | ||||
| @@ -60,8 +60,8 @@ int main(int argc, const char* argv[]) { | ||||
|  | ||||
|     auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|     Render(screen, document); | ||||
|     std::cout << reset_position << screen.ToString() << std::flush; | ||||
|  | ||||
|     std::cout << reset_position; | ||||
|     screen.Print(); | ||||
|     reset_position = screen.ResetPosition(); | ||||
|  | ||||
|     std::this_thread::sleep_for(0.03s); | ||||
|   | ||||
| @@ -39,7 +39,7 @@ int main(int argc, const char* argv[]) { | ||||
|  | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|   std::cout << screen.ToString() << std::endl; | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -41,8 +41,8 @@ int main(int argc, const char* argv[]) { | ||||
|  | ||||
|     auto screen = Screen::Create(Dimension::Full()); | ||||
|     Render(screen, document); | ||||
|     std::cout << reset_position << screen.ToString() << std::flush; | ||||
|  | ||||
|     std::cout << reset_position; | ||||
|     screen.Print(); | ||||
|     reset_position = screen.ResetPosition(); | ||||
|  | ||||
|     std::this_thread::sleep_for(0.01s); | ||||
|   | ||||
| @@ -123,7 +123,8 @@ int main(int argc, const char* argv[]) { | ||||
|     auto document = render(); | ||||
|     auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|     Render(screen, document); | ||||
|     std::cout << reset_position << screen.ToString() << std::flush; | ||||
|     std::cout << reset_position; | ||||
|     screen.Print(); | ||||
|     reset_position = screen.ResetPosition(); | ||||
|  | ||||
|     // Simulate time. | ||||
|   | ||||
| @@ -25,7 +25,7 @@ int main(int argc, const char* argv[]) { | ||||
|  | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Full()); | ||||
|   Render(screen, document); | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|   getchar(); | ||||
|  | ||||
|   return 0; | ||||
|   | ||||
| @@ -18,8 +18,7 @@ int main(int argc, const char* argv[]) { | ||||
|                   border; | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString() << std::endl; | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -18,7 +18,7 @@ int main(int argc, const char* argv[]) { | ||||
|   auto document = hbox(std::move(content)); | ||||
|   auto screen = Screen::Create(Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|   std::cout << screen.ToString() << std::endl; | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -28,7 +28,8 @@ int main(int argc, const char* argv[]) { | ||||
|     }); | ||||
|     auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|     Render(screen, document); | ||||
|     std::cout << reset_position << screen.ToString() << std::flush; | ||||
|     std::cout << reset_position; | ||||
|     screen.Print(); | ||||
|     reset_position = screen.ResetPosition(); | ||||
|  | ||||
|     std::this_thread::sleep_for(0.1s); | ||||
|   | ||||
| @@ -12,8 +12,7 @@ int main(int argc, const char* argv[]) { | ||||
|       }); | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -12,8 +12,7 @@ int main(int argc, const char* argv[]) { | ||||
|       }); | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -51,8 +51,7 @@ int main(int argc, const char* argv[]) { | ||||
|  | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -12,8 +12,7 @@ int main(int argc, const char* argv[]) { | ||||
|       }); | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -19,8 +19,7 @@ int main(int argc, const char* argv[]) { | ||||
|   // clang-format on | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -11,8 +11,7 @@ int main(int argc, const char* argv[]) { | ||||
|   }); | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -12,8 +12,7 @@ int main(int argc, const char* argv[]) { | ||||
|       }); | ||||
|   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -26,8 +26,7 @@ int main(int argc, const char* argv[]) { | ||||
|       }); | ||||
|   auto screen = Screen::Create(Dimension::Full()); | ||||
|   Render(screen, document); | ||||
|  | ||||
|   std::cout << screen.ToString(); | ||||
|   screen.Print(); | ||||
|   getchar(); | ||||
|  | ||||
|   return 0; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ int main(void) { | ||||
|  | ||||
|   auto screen = Screen::Create(Dimension::Fixed(80), Dimension::Fixed(10)); | ||||
|   Render(screen, document); | ||||
|   std::cout << screen.ToString() << '\n'; | ||||
|   screen.Print(); | ||||
| } | ||||
|  | ||||
| // Copyright 2020 Arthur Sonzogni. All rights reserved. | ||||
|   | ||||
							
								
								
									
										164
									
								
								examples/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								examples/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| <!DOCTYPE html> <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <title>FTXUI examples WebAssembly</title> | ||||
|     <script src="https://cdn.jsdelivr.net/npm/xterm@4.11.0/lib/xterm.min.js"></script> | ||||
|     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.11.0/css/xterm.css"></link> | ||||
|   </head> | ||||
|   <body> | ||||
|     <script id="example_script"></script> | ||||
|     <div class="page"> | ||||
|       <h1>FTXUI WebAssembly Example </h1> | ||||
|       <p> | ||||
|         <a href="https://github.com/ArthurSonzogni/FTXUI">FTXUI</a> is a single | ||||
|         C++ library for terminal user interface. | ||||
|       </p> | ||||
|       <p> | ||||
|         On this page, you can try all the examples contained in: <a | ||||
|         href="https://github.com/ArthurSonzogni/FTXUI/tree/master/examples">./example/</a> | ||||
|         Those are compiled using WebAssembly. | ||||
|       </p> | ||||
|       <select id="selectExample"></select> | ||||
|       <div id="terminal"></div> | ||||
|     </div> | ||||
|   </body> | ||||
|   <script> | ||||
|     let example_list = [ | ||||
|       "./component/button.js", | ||||
|       "./component/checkbox.js", | ||||
|       "./component/checkbox_in_frame.js", | ||||
|       "./component/gallery.js", | ||||
|       "./component/homescreen.js", | ||||
|       "./component/input.js", | ||||
|       "./component/menu.js", | ||||
|       "./component/menu2.js", | ||||
|       "./component/menu_style.js", | ||||
|       "./component/radiobox.js", | ||||
|       "./component/radiobox_in_frame.js", | ||||
|       "./component/tab_horizontal.js", | ||||
|       "./component/tab_vertical.js", | ||||
|       "./component/toggle.js", | ||||
|       "./component/modal_dialog.js", | ||||
|  | ||||
|       "./dom/border.js", | ||||
|       "./dom/color_gallery.js", | ||||
|       "./dom/dbox.js", | ||||
|       "./dom/gauge.js", | ||||
|       "./dom/graph.js", | ||||
|       "./dom/hflow.js", | ||||
|       "./dom/html_like.js", | ||||
|       "./dom/package_manager.js", | ||||
|       "./dom/paragraph.js", | ||||
|       "./dom/separator.js", | ||||
|       "./dom/size.js", | ||||
|       "./dom/spinner.js", | ||||
|       "./dom/style_blink.js", | ||||
|       "./dom/style_bold.js", | ||||
|       "./dom/style_color.js", | ||||
|       "./dom/color_truecolor_RGB.js", | ||||
|       "./dom/color_truecolor_HSV.js", | ||||
|       "./dom/color_info_palette256.js", | ||||
|       "./dom/style_dim.js", | ||||
|       "./dom/style_gallery.js", | ||||
|       "./dom/style_inverted.js", | ||||
|       "./dom/style_underlined.js", | ||||
|       "./dom/vbox_hbox.js", | ||||
|       "./dom/window.js", | ||||
|  | ||||
|       "./util/print_key_press.js", | ||||
|     ]; | ||||
|  | ||||
|     const url_search_params = new URLSearchParams(window.location.search); | ||||
|     const example_index = url_search_params.get("id") || 16; | ||||
|     const example = example_list[example_index]; | ||||
|  | ||||
|     var select = document.getElementById("selectExample");  | ||||
|  | ||||
|     for(var i = 0; i < example_list.length; i++) { | ||||
|         var opt = example_list[i]; | ||||
|         var el = document.createElement("option"); | ||||
|         el.textContent = opt; | ||||
|         el.value = opt; | ||||
|         select.appendChild(el); | ||||
|     } | ||||
|     select.selectedIndex = example_index; | ||||
|     select.addEventListener("change", () => { | ||||
|       location.href = (location.href).split('?')[0] + "?id=" + select.selectedIndex; | ||||
|     }); | ||||
|  | ||||
|     let stdin_buffer = []; | ||||
|     let stdin = () => { | ||||
|       return stdin_buffer.shift() || 0; | ||||
|     } | ||||
|  | ||||
|     stdout_buffer = []; | ||||
|     let stdout = code => { | ||||
|       if (code == 0) { | ||||
|         term.write(new Uint8Array(stdout_buffer)); | ||||
|         stdout_buffer = []; | ||||
|       } else { | ||||
|         stdout_buffer.push(code) | ||||
|       } | ||||
|     } | ||||
|     let stderr = code => console.log(code); | ||||
|     var term = new Terminal(); | ||||
|     term.open(document.querySelector('#terminal')); | ||||
|     term.resize(140,43); | ||||
|     const onBinary = e => { | ||||
|       for(c of e) | ||||
|         stdin_buffer.push(c.charCodeAt(0)); | ||||
|     } | ||||
|     term.onBinary(onBinary); | ||||
|     term.onData(onBinary) | ||||
|     window.Module = { | ||||
|       preRun: () => { FS.init(stdin, stdout, stderr); }, | ||||
|       postRun: [], | ||||
|       onRuntimeInitialized: () => {}, | ||||
|     }; | ||||
|     document.querySelector("#example_script").src = example | ||||
|   </script> | ||||
|  | ||||
|   <style> | ||||
|     body { | ||||
|       background-color:#EEE; | ||||
|       padding:20px; | ||||
|       font-family: Helvetica, sans-serif; | ||||
|       font-size: 130%; | ||||
|     } | ||||
|  | ||||
|     .page { | ||||
|       max-width:1300px; | ||||
|       margin: auto; | ||||
|     } | ||||
|  | ||||
|     h1 { | ||||
|       text-decoration: underline; | ||||
|     } | ||||
|  | ||||
|     select { | ||||
|       display:block; | ||||
|       padding: .6em 1.4em .5em .8em; | ||||
|       border-radius: 20px 20px 0px 0px; | ||||
|       font-size: 16px; | ||||
|       font-family: sans-serif; | ||||
|       font-weight: 700; | ||||
|  | ||||
|       color: #444; | ||||
|       line-height: 1.3; | ||||
|       background-color:black; | ||||
|       border:0px; | ||||
|       color:white; | ||||
|       transition: color 0.2s linear; | ||||
|       transition: background-color 0.2s linear; | ||||
|     } | ||||
|  | ||||
|     #terminal { | ||||
|       padding:10px; | ||||
|       border:none; | ||||
|       background-color:black; | ||||
|       padding:auto; | ||||
|     } | ||||
|  | ||||
|   </style> | ||||
|  | ||||
| </html> | ||||
							
								
								
									
										6
									
								
								examples/run_webassembly.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								examples/run_webassembly.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| #! /bin/bash | ||||
| python3 -m http.server 8888 & | ||||
| P1=$! | ||||
| trap 'kill 0' SIGINT; P1 | ||||
| python3 -m webbrowser http://localhost:8888 | ||||
| wait $P1 | ||||
		Reference in New Issue
	
	Block a user
	 ArthurSonzogni
					ArthurSonzogni