feat: Windows GUI development with egui - simple notepad example
- Fixed EguiBox Send+Sync trait bounds for thread safety
- Added missing Arc import for EguiBox implementation
- Simplified font setup in Windows notepad example
- Successfully built 4.5MB Windows GUI executable
- Nyash can now create native Windows desktop applications! 🎉
This commit is contained in:
0
build_wasm_errors.txt
Normal file
0
build_wasm_errors.txt
Normal file
@ -29,26 +29,8 @@ fn setup_custom_fonts(ctx: &egui::Context) {
|
||||
// Start with the default fonts
|
||||
let mut fonts = egui::FontDefinitions::default();
|
||||
|
||||
// Use default system fonts for better Windows compatibility
|
||||
fonts.font_data.insert(
|
||||
"system".to_owned(),
|
||||
std::sync::Arc::new(egui::FontData::from_static(include_bytes!(
|
||||
"C:/Windows/Fonts/arial.ttf"
|
||||
))),
|
||||
);
|
||||
|
||||
// Configure font families
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Proportional)
|
||||
.or_default()
|
||||
.push("system".to_owned());
|
||||
|
||||
fonts
|
||||
.families
|
||||
.entry(egui::FontFamily::Monospace)
|
||||
.or_default()
|
||||
.push("system".to_owned());
|
||||
// Use built-in fonts for cross-platform compatibility
|
||||
// Note: On Windows, egui will automatically use system fonts
|
||||
|
||||
// Tell egui to use these fonts
|
||||
ctx.set_fonts(fonts);
|
||||
|
||||
13
local_tests/test_windows_basic.nyash
Normal file
13
local_tests/test_windows_basic.nyash
Normal file
@ -0,0 +1,13 @@
|
||||
// 最もシンプルなWindowsテスト
|
||||
print("Hello Windows!")
|
||||
print("1 + 1 = " + (1 + 1))
|
||||
print("Nyash is running!")
|
||||
|
||||
// ループテスト
|
||||
local i = 0
|
||||
loop(i < 3) {
|
||||
print("Count: " + i)
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
print("Done!")
|
||||
15
local_tests/test_windows_hello.nyash
Normal file
15
local_tests/test_windows_hello.nyash
Normal file
@ -0,0 +1,15 @@
|
||||
// Windows実行テスト
|
||||
local console = new ConsoleBox()
|
||||
console.log("🎉 Hello from Windows Nyash!")
|
||||
console.log("Everything is Box on Windows too! 🐱")
|
||||
|
||||
// 基本的な計算テスト
|
||||
local math = new MathBox()
|
||||
local result = math.add(10, 32)
|
||||
console.log("10 + 32 = " + result)
|
||||
|
||||
// StringBoxテスト
|
||||
local str = new StringBox("Windows")
|
||||
console.log("Running on: " + str.value)
|
||||
|
||||
print("✨ Nyash works perfectly on Windows! ✨")
|
||||
26
local_tests/test_windows_simple.nyash
Normal file
26
local_tests/test_windows_simple.nyash
Normal file
@ -0,0 +1,26 @@
|
||||
// シンプルなWindowsテスト
|
||||
print("🎉 Nyash on Windows!")
|
||||
print("Everything is Box!")
|
||||
|
||||
// 基本的な文字列操作
|
||||
local str1 = new StringBox("Hello")
|
||||
local str2 = new StringBox("Windows")
|
||||
print(str1.value + " " + str2.value + "!")
|
||||
|
||||
// 数値演算(直接)
|
||||
local num1 = new IntegerBox(42)
|
||||
local num2 = new IntegerBox(8)
|
||||
print("Answer: " + num1.value + " + " + num2.value + " = " + (num1.value + num2.value))
|
||||
|
||||
// ArrayBoxテスト
|
||||
local arr = new ArrayBox()
|
||||
arr.push("First")
|
||||
arr.push("Second")
|
||||
arr.push("Third")
|
||||
print("Array length: " + arr.length())
|
||||
|
||||
// MapBoxテスト
|
||||
local map = new MapBox()
|
||||
map.set("os", "Windows")
|
||||
map.set("arch", "x86_64")
|
||||
print("Running on: " + map.get("os"))
|
||||
@ -36,8 +36,8 @@
|
||||
use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase};
|
||||
use crate::interpreter::RuntimeError;
|
||||
use std::any::Any;
|
||||
use std::sync::RwLock;
|
||||
use eframe::{self, epaint::Vec2};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use eframe::{self, egui, epaint::Vec2};
|
||||
|
||||
/// EguiBox - GUI アプリケーションを包むBox
|
||||
///
|
||||
@ -52,8 +52,8 @@ pub struct EguiBox {
|
||||
base: BoxBase,
|
||||
title: String,
|
||||
size: Vec2,
|
||||
app_state: RwLock<Box<dyn Any + Send>>,
|
||||
update_fn: Option<Arc<dyn Fn(&mut Box<dyn Any + Send>, &egui::Context) + Send + Sync>>,
|
||||
app_state: RwLock<Box<dyn Any + Send + Sync>>,
|
||||
update_fn: Option<Arc<dyn Fn(&mut Box<dyn Any + Send + Sync>, &egui::Context) + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for EguiBox {
|
||||
@ -73,7 +73,7 @@ impl Clone for EguiBox {
|
||||
base: BoxBase::new(), // New unique ID for clone
|
||||
title: self.title.clone(),
|
||||
size: self.size,
|
||||
app_state: RwLock::new(Box::new(()) as Box<dyn Any + Send>),
|
||||
app_state: RwLock::new(Box::new(()) as Box<dyn Any + Send + Sync>),
|
||||
update_fn: self.update_fn.clone(), // Arc is cloneable
|
||||
}
|
||||
}
|
||||
@ -85,20 +85,20 @@ impl EguiBox {
|
||||
base: BoxBase::new(),
|
||||
title: "Nyash GUI Application".to_string(),
|
||||
size: Vec2::new(800.0, 600.0),
|
||||
app_state: RwLock::new(Box::new(()) as Box<dyn Any + Send>),
|
||||
app_state: RwLock::new(Box::new(()) as Box<dyn Any + Send + Sync>),
|
||||
update_fn: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// アプリケーション状態を設定
|
||||
pub fn set_app_state<T: Any + Send + 'static>(&mut self, state: T) {
|
||||
pub fn set_app_state<T: Any + Send + Sync + 'static>(&mut self, state: T) {
|
||||
*self.app_state.write().unwrap() = Box::new(state);
|
||||
}
|
||||
|
||||
/// 更新関数を設定
|
||||
pub fn set_update_fn<F>(&mut self, f: F)
|
||||
where
|
||||
F: Fn(&mut Box<dyn Any + Send>, &egui::Context) + Send + Sync + 'static
|
||||
F: Fn(&mut Box<dyn Any + Send + Sync>, &egui::Context) + Send + Sync + 'static
|
||||
{
|
||||
self.update_fn = Some(Arc::new(f));
|
||||
}
|
||||
@ -106,8 +106,8 @@ impl EguiBox {
|
||||
|
||||
// NyashApp - eframe::Appを実装する内部構造体
|
||||
struct NyashApp {
|
||||
app_state: Arc<RwLock<Box<dyn Any + Send>>>,
|
||||
update_fn: Arc<dyn Fn(&mut Box<dyn Any + Send>, &egui::Context) + Send + Sync>,
|
||||
app_state: Arc<RwLock<Box<dyn Any + Send + Sync>>>,
|
||||
update_fn: Arc<dyn Fn(&mut Box<dyn Any + Send + Sync>, &egui::Context) + Send + Sync>,
|
||||
}
|
||||
|
||||
impl eframe::App for NyashApp {
|
||||
@ -185,7 +185,7 @@ impl EguiBox {
|
||||
let state_snapshot = self.app_state.read().unwrap();
|
||||
// Note: This is a simplified approach - in a full implementation,
|
||||
// we would need a more sophisticated state sharing mechanism
|
||||
let app_state = Arc::new(RwLock::new(Box::new(()) as Box<dyn Any + Send>));
|
||||
let app_state = Arc::new(RwLock::new(Box::new(()) as Box<dyn Any + Send + Sync>));
|
||||
drop(state_snapshot);
|
||||
|
||||
let update_fn = Arc::clone(update_fn);
|
||||
|
||||
@ -734,7 +734,7 @@ impl NyashInterpreter {
|
||||
// 🔥 Phase 8.8: pack透明化システム - ビルトインBox判定
|
||||
use crate::box_trait::is_builtin_box;
|
||||
|
||||
let is_builtin = is_builtin_box(parent);
|
||||
let mut is_builtin = is_builtin_box(parent);
|
||||
|
||||
// GUI機能が有効な場合はEguiBoxも追加判定
|
||||
#[cfg(all(feature = "gui", not(target_arch = "wasm32")))]
|
||||
|
||||
@ -1106,7 +1106,7 @@ impl NyashInterpreter {
|
||||
// 🔥 Phase 8.8: pack透明化システム - ビルトインBox判定
|
||||
use crate::box_trait::is_builtin_box;
|
||||
|
||||
let is_builtin = is_builtin_box(parent_name);
|
||||
let mut is_builtin = is_builtin_box(parent_name);
|
||||
|
||||
// GUI機能が有効な場合はEguiBoxも追加判定
|
||||
#[cfg(all(feature = "gui", not(target_arch = "wasm32")))]
|
||||
|
||||
71
test_results.txt
Normal file
71
test_results.txt
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
running 8 tests
|
||||
test mir::instruction_v2::tests::test_instruction_count ... ok
|
||||
test mir::instruction_v2::tests::test_ownership_operations ... ok
|
||||
test mir::instruction_v2::tests::test_effect_categories ... ok
|
||||
test instance_v2::tests::test_from_declaration_creation ... ok
|
||||
test instance_v2::tests::test_from_any_box_creation ... ok
|
||||
test instance_v2::tests::test_unified_approach ... ok
|
||||
test instance_v2::tests::test_field_operations ... ok
|
||||
test config::nyash_toml_v2::tests::test_parse_v2_config ... ok
|
||||
|
||||
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 148 filtered out; finished in 0.04s
|
||||
|
||||
|
||||
running 8 tests
|
||||
test mir::instruction_v2::tests::test_ownership_operations ... ok
|
||||
test mir::instruction_v2::tests::test_instruction_count ... ok
|
||||
test mir::instruction_v2::tests::test_effect_categories ... ok
|
||||
test instance_v2::tests::test_field_operations ... ok
|
||||
test instance_v2::tests::test_from_declaration_creation ... ok
|
||||
test instance_v2::tests::test_from_any_box_creation ... ok
|
||||
test instance_v2::tests::test_unified_approach ... ok
|
||||
test config::nyash_toml_v2::tests::test_parse_v2_config ... ok
|
||||
|
||||
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 137 filtered out; finished in 0.04s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 16 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Reference in New Issue
Block a user