Newer
Older
//! This example demonstrates how one might create a tab system
//!
//! Additionally, it showcases focus navigation. Press `Tab` and `Shift + Tab` to move
//! between focusable widgets. This example also sets it up so that `Enter` or `Space`
//! can be used in place of a normal click.
use bevy::{
prelude::{App as BevyApp, AssetServer, Commands, Res, ResMut},
window::WindowDescriptor,
DefaultPlugins,
};
use kayak_ui::{
bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle},
core::{
styles::{Style, StyleProp, Units},
Children, Color, constructor, Index, render, rsx, widget
},
widgets::{App, Text, Window},
};
use tab_box::TabBox;
use tab_box::TabData;
use crate::theming::{ColorState, TabTheme, TabThemeProvider};
mod tab_bar;
mod tab_box;
mod tab_content;
mod tab;
mod theming;
#[widget]
fn TabDemo() {
let text_style = Style {
width: StyleProp::Value(Units::Percentage(75.0)),
top: StyleProp::Value(Units::Stretch(0.5)),
left: StyleProp::Value(Units::Stretch(1.0)),
bottom: StyleProp::Value(Units::Stretch(1.0)),
right: StyleProp::Value(Units::Stretch(1.0)),
..Default::default()
};
// TODO: This is not the most ideal way to generate tabs. For one, the `content` has no access to its actual context
// (i.e. where it actually exists in the hierarchy). Additionally, it would be better if tabs were created as
// children of `TabBox`. These are issues that will be addressed in the future, so for now, this will work.
let tabs = vec![
// This is a temporary hack to prevent the `constructor` macro from throwing an error
let children = Children::None;
let text_style = text_style.clone();
constructor! {
<>
<Text content={"Welcome to Tab 1!".to_string()} size={48.0} styles={Some(text_style)} />
</>
}
},
},
TabData {
name: "Tab 2".to_string(),
content: {
let children = Children::None;
let text_style = text_style.clone();
constructor! {
<>
<Text content={"Welcome to Tab 2!".to_string()} size={48.0} styles={Some(text_style)} />
</>
}
},
},
TabData {
name: "Tab 3".to_string(),
content: {
let children = Children::None;
let text_style = text_style.clone();
constructor! {
<>
<Text content={"Welcome to Tab 3!".to_string()} size={48.0} styles={Some(text_style)} />
</>
}
},
},
}
}
fn startup(
mut commands: Commands,
mut font_mapping: ResMut<FontMapping>,
asset_server: Res<AssetServer>,
) {
commands.spawn_bundle(UICameraBundle::new());
font_mapping.add(asset_server.load("roboto.kayak_font"));
let theme = TabTheme {
primary: Default::default(),
bg: Color::new(0.176, 0.227, 0.255, 1.0),
fg: Color::new(0.286, 0.353, 0.392, 1.0),
focus: Color::new(0.388, 0.474, 0.678, 0.5),
text: ColorState {
normal: Color::new(0.949, 0.956, 0.968, 1.0),
hovered: Color::new(0.650, 0.574, 0.669, 1.0),
active: Color::new(0.949, 0.956, 0.968, 1.0),
},
active_tab: ColorState {
normal: Color::new(0.286, 0.353, 0.392, 1.0),
hovered: Color::new(0.246, 0.323, 0.352, 1.0),
active: Color::new(0.196, 0.283, 0.312, 1.0),
},
inactive_tab: ColorState {
normal: Color::new(0.176, 0.227, 0.255, 1.0),
hovered: Color::new(0.16, 0.21, 0.23, 1.0),
active: Color::new(0.196, 0.283, 0.312, 1.0),
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
},
tab_height: 22.0,
};
let context = BevyContext::new(|context| {
render! {
<App>
<Window position={(50.0, 50.0)} size={(600.0, 300.0)} title={"Tabs Example".to_string()}>
<TabThemeProvider initial_theme={theme}>
<TabDemo />
</TabThemeProvider>
</Window>
</App>
}
});
commands.insert_resource(context);
}
fn main() {
BevyApp::new()
.insert_resource(WindowDescriptor {
width: 1270.0,
height: 720.0,
title: String::from("UI Example"),
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(BevyKayakUIPlugin)
.add_startup_system(startup)
.run();