//! Show a custom window frame instead of the default OS window chrome decorations.
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
#![allow(rustdoc::missing_crate_level_docs)] // it's an example
use eframe::egui::{self, ViewportCommand};
use eframe::epaint::Stroke;
use egui::epaint::text::FontInsert;
use egui::{
Atom, Button, Color32, ComboBox, CornerRadius, FontData, FontDefinitions, FontFamily, FontId,
Id, RichText, TextEdit, Vec2, include_image,
};
use std::ops::Deref;
use std::sync::{Arc, Mutex};
use std::thread::sleep;
use std::time::Duration;
fn main() -> eframe::Result {
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_decorations(false) // Hide the OS-specific "chrome" around the window
.with_inner_size([400.0, 200.0])
.with_min_inner_size([400.0, 200.0])
.with_max_inner_size([400.0, 200.0]),
..Default::default()
};
//let mut cli_lock: Arc<Mutex<Option<Cli>>> = Arc::new(Mutex::new(None));
//let c2 = cli_lock.clone();
eframe::run_native(
"Custom window frame", // unused title
options,
Box::new(|cc| {
egui_extras::install_image_loaders(&cc.egui_ctx);
let mut fonts = FontDefinitions::empty();
fonts.font_data.insert(
"Inter-Regular".to_string(),
Arc::new(FontData::from_static(include_bytes!("Inter-Regular.otf"))),
);
fonts.font_data.insert(
"Inter-SemiBold".to_string(),
Arc::new(FontData::from_static(include_bytes!("Inter-SemiBold.otf"))),
);
fonts
.families
.insert(FontFamily::Proportional, vec!["Inter-Regular".to_string()]);
fonts.families.insert(
FontFamily::Name("semibold".into()),
vec!["Inter-SemiBold".to_string()],
);
cc.egui_ctx.set_fonts(fonts);
cc.egui_ctx.style_mut(|u| {
u.visuals.override_text_color = Some(egui::Color32::from_hex("#cdd6f4").unwrap());
u.visuals.weak_text_color = Some(egui::Color32::from_hex("#7f849c").unwrap());
u.compact_menu_style = true;
});
Ok(Box::new(MyApp {
selected_server: Server {
name: "US - East".to_string(),
is_prod: true,
url: "wss://stk.e3t.cc".to_string(),
},
username: "core".to_string(),
//cli_lock
}))
}),
)
.unwrap();
//if let Some(cli) = c2.lock().as_ref().unwrap().deref() {
// starkingdoms::native_entrypoint::start(cli.clone());
//}
Ok(())
}
struct MyApp {
selected_server: Server,
//cli_lock: Arc<Mutex<Option<Cli>>>,
username: String,
}
#[derive(PartialEq)]
struct Server {
name: String,
is_prod: bool,
url: String,
}
impl eframe::App for MyApp {
fn clear_color(&self, _visuals: &egui::Visuals) -> [f32; 4] {
egui::Rgba::TRANSPARENT.to_array() // Make sure we don't paint anything behind the rounded corners
}
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
custom_window_frame(ctx, "starkingdoms", |ui| {
ui.heading(
RichText::new("StarKingdoms")
.font(FontId::new(24.0, FontFamily::Name("semibold".into()))),
);
ui.add_space(10.0);
ui.style_mut().visuals.widgets.inactive.weak_bg_fill = Color32::TRANSPARENT;
ui.style_mut().visuals.widgets.inactive.bg_stroke =
Stroke::new(1.0, Color32::from_hex("#89b4fa").unwrap());
ui.style_mut().visuals.widgets.inactive.fg_stroke =
Stroke::new(1.0, Color32::from_hex("#89b4fa").unwrap());
if ui
.add(Button::new((
Atom::custom(Id::new("left-space"), Vec2::new(64.0, 24.0)),
RichText::new("Launch!")
.font(FontId::new(12.0, FontFamily::Name("semibold".into())))
.color(Color32::from_hex("#89b4fa").unwrap()),
Atom::custom(Id::new("right-space"), Vec2::new(64.0, 24.0)),
)))
.clicked()
{
//let cli = Cli::Client {
// server: self.selected_server.url.clone(),
//};
//println!("starting client with arguments: {:?}", cli);
//*self.cli_lock.lock().unwrap() = Some(cli);
let ctx = ctx.clone();
std::thread::spawn(move || {
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
});
}
ui.style_mut().visuals.widgets.inactive.bg_stroke = Stroke::NONE;
ui.add_space(10.0);
ui.style_mut().visuals.widgets.active.weak_bg_fill = Color32::TRANSPARENT;
ui.style_mut().visuals.widgets.hovered.weak_bg_fill = Color32::TRANSPARENT;
ui.vertical(|ui| {
ui.horizontal(|ui| {
ui.label(RichText::new("joining as").size(10.0).weak());
ui.add(
TextEdit::singleline(&mut self.username)
.text_color(Color32::from_hex("#89b4fa").unwrap())
.font(FontId::new(10.0, FontFamily::Name("semibold".into()))),
);
});
ui.horizontal(|ui| {
ui.label(RichText::new("connecting to").size(10.0).weak());
let servers = vec![
Server {
name: "US - East".to_string(),
is_prod: true,
url: "wss://stk.e3t.cc".to_string(),
},
Server {
name: "Local Development".to_string(),
is_prod: false,
url: "ws://localhost:5151".to_string(),
},
];
ComboBox::new("combobox", "")
.selected_text(match self.selected_server.is_prod {
true => srv_string(&self.selected_server.name),
false => nonprod_srv_string(&self.selected_server.name),
})
.icon(|_, _, _, _| {})
.show_ui(ui, |ui| {
for srv in servers {
let s = match srv.is_prod {
true => srv_string(&srv.name),
false => nonprod_srv_string(&srv.name),
};
ui.selectable_value(&mut self.selected_server, srv, s);
}
});
});
});
});
}
}
fn custom_window_frame(ctx: &egui::Context, title: &str, add_contents: impl FnOnce(&mut egui::Ui)) {
use egui::{CentralPanel, UiBuilder};
let panel_frame = egui::Frame::new()
.fill(ctx.style().visuals.window_fill())
.corner_radius(10);
CentralPanel::default().frame(panel_frame).show(ctx, |ui| {
egui::Image::new(egui::include_image!("../bg.png")).paint_at(ui, ui.ctx().screen_rect());
//ui.image(include_image!("bg.png"));
let app_rect = ui.max_rect();
// Add the contents:
let content_rect = app_rect.shrink(8.0);
let mut content_ui = ui.new_child(UiBuilder::new().max_rect(content_rect));
add_contents(&mut content_ui);
});
}
fn srv_string(lbl: &str) -> RichText {
RichText::new(lbl)
.color(Color32::from_hex("#89b4fa").unwrap())
.font(FontId::new(10.0, FontFamily::Name("semibold".into())))
}
fn nonprod_srv_string(lbl: &str) -> RichText {
RichText::new(format!("⚠ {lbl}"))
.color(Color32::from_hex("#f9e2af").unwrap())
.font(FontId::new(10.0, FontFamily::Name("semibold".into())))
}