Commit 1671be11 authored by Florian Blasius's avatar Florian Blasius
Browse files

create cargo workspace

add calendar from kivimangao
add calculator from flovanro
parent 8dc5fdf8
This diff is collapsed.
[package]
name = "orbutils"
description = "The Orbital Utilities"
repository = "https://gitlab.redox-os.org/redox-os/orbutils"
version = "0.1.16"
license-file = "LICENSE"
readme = "README.md"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
[[bin]]
name = "background"
path = "src/background/main.rs"
[[bin]]
name = "calculator"
path = "src/calculator/main.rs"
[[bin]]
name = "character_map"
path = "src/character_map/main.rs"
[[bin]]
name = "editor"
path = "src/editor/main.rs"
[[bin]]
name = "file_manager"
path = "src/file_manager/main.rs"
[[bin]]
name = "launcher"
path = "src/launcher/main.rs"
[[bin]]
name = "orblogin"
path = "src/orblogin/main.rs"
[[bin]]
name = "viewer"
path = "src/viewer/main.rs"
[[bin]]
name = "calendar"
path = "src/calendar/main.rs"
[dependencies]
calculate = { git = "https://gitlab.redox-os.org/redox-os/calc.git" }
chrono = "0.4.6"
mime_guess = "1.8.6"
mime = "0.2.6"
orbclient = "0.3.24"
orbfont = "0.1.8"
orbimage = "0.1.17"
orbtk = "0.2.29"
redox_users = "0.3.1"
[target.'cfg(not(target_os = "redox"))'.dependencies]
libc = "0.2.50"
[target.'cfg(target_os = "redox")'.dependencies]
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git" }
redox_syscall = "0.1.51"
[workspace]
members = [
"background",
"calculator",
"calendar",
"character_map",
"editor",
"file_manager",
"launcher",
"orblogin",
"viewer",
]
\ No newline at end of file
[package]
name = "background"
version = "0.1.0"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
edition = "2018"
license-file = "../LICENSE"
readme = "../README.md"
repository = "https://gitlab.redox-os.org/redox-os/orbutils"
[[bin]]
name = "background"
path = "background.rs"
[dependencies]
orbclient = { git = "https://gitlab.redox-os.org/redox-os/orbclient.git" }
orbimage = { git = "https://gitlab.redox-os.org/redox-os/orbimage.git", branch = "develop" }
\ No newline at end of file
[package]
name = "calculator"
version = "0.1.0"
authors = ["Florian Blasius <flovanpt@posteo.de>"]
edition = "2018"
license-file = "../LICENSE"
readme = "../README.md"
repository = "https://gitlab.redox-os.org/redox-os/orbutils"
[[bin]]
name = "calculator"
path = "calculator.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
orbtk = { git = "https://github.com/redox-os/orbtk.git", branch = "develop" }
calculate = { git = "https://gitlab.redox-os.org/redox-os/calc.git" }
lazy_static = "1.4.0"
[features]
light = []
redox = []
[package.metadata.bundle]
name = "Calculator"
identifier = "redox-os.calculator"
short_description = "Calculator written in rust, developed with OrbTk."
Theme (
styles: {
"input": (
base: "body",
properties: {
"font_family": "$REGULAR_FONT",
"foreground": "$CADET_BLUE"
}
),
"result": (
base: "body",
properties: {
"font_size": "$FONT_SIZE_36",
"foreground": "$LINK_WATER"
}
),
"header_area": (
properties: {
"background": "$RIVER_BAD"
}
),
"content_area": (
properties: {
"background": "$BRIGHT_GRAY"
}
),
"button_calculator": (
base: "base",
properties: {
"width": 48,
"height": 48,
"foreground": "$LINK_WATER",
"icon_brush": "$LINK_WATER",
"background": "$LYNCH",
"border_radius": 1,
"spacing": 0,
},
states: {
"pressed": {
"background": "$BLUE_BAYOUX",
},
"selected": {
"background": "$BLUE_BAYOUX",
},
"disabled": {
"background": "$ROLLING_STONE",
"foreground": "$BRIGHT_GRAY",
"icon_brush": "$BRIGHT_GRAY",
},
},
),
"button_calculator_primary": (
base: "button_calculator",
properties: {
"background": "$GOLDEN_DREAM",
"foreground": "$BRIGHT_GRAY",
"icon_brush": "$BRIGHT_GRAY",
},
),
}
)
\ No newline at end of file
Theme (
styles: {
"input": (
base: "body",
properties: {
"font_family": "$REGULAR_FONT",
"foreground": "$BRIGHT_GRAY"
}
),
"result": (
base: "body",
properties: {
"font_size": "$FONT_SIZE_36",
"foreground": "$BRIGHT_GRAY"
}
),
"header_area": (
properties: {
"background": "$WHITE"
}
),
"content_area": (
properties: {
"background": "$ALABASTER"
}
),
"button_calculator": (
base: "base",
properties: {
"width": 48,
"height": 48,
"foreground": "$BRIGHT_GRAY",
"icon_brush": "$BRIGHT_GRAY",
"background": "$ALTO",
"border_radius": 1,
"spacing": 0,
},
states: {
"pressed": {
"background": "$SILVER_CHALICE",
},
"selected": {
"background": "$SILVER_CHALICE",
},
"disabled": {
"background": "$ROLLING_STONE",
"foreground": "$BRIGHT_GRAY",
"icon_brush": "$BRIGHT_GRAY",
},
},
),
"button_calculator_primary": (
base: "button_calculator",
properties: {
"background": "$GOLDEN_DREAM",
"foreground": "$BRIGHT_GRAY",
"icon_brush": "$BRIGHT_GRAY",
},
),
}
)
\ No newline at end of file
Theme (
styles: {
"input": (
base: "body",
properties: {
"font_family": "$REGULAR_FONT",
"foreground": "$BRIGHT_GRAY"
}
),
"result": (
base: "body",
properties: {
"font_size": "$FONT_SIZE_36",
"foreground": "$BRIGHT_GRAY"
}
),
"header_area": (
properties: {
"background": "$WHITE"
}
),
"content_area": (
properties: {
"background": "$ATHENS_GREY"
}
),
"button_calculator": (
base: "base",
properties: {
"width": 48,
"height": 48,
"foreground": "$BLACK",
"icon_brush": "$BLACK",
"background": "$WHITE",
"border_brush": "$BOTTICELLI",
"border_width": 1,
"border_radius": 2,
"spacing": 0,
},
states: {
"pressed": {
"background": "$HAVELOCK_BLUE",
"icon_brush": "$WHITE",
"foreground": "$WHITE"
},
"selected": {
"background": "$HAVELOCK_BLUE",
"icon_brush": "$WHITE",
"foreground": "$WHITE"
},
"disabled": {
"background": "$ROLLING_STONE",
"foreground": "$BRIGHT_GRAY",
"icon_brush": "$BRIGHT_GRAY",
},
},
),
"button_calculator_primary": (
base: "button_calculator",
properties: {
"background": "$HAVELOCK_BLUE",
"foreground": "$WHITE",
"icon_brush": "$WHITE",
},
states: {
"pressed": {
"background": "#5277E2",
},
},
),
}
)
\ No newline at end of file
use std::collections::VecDeque;
use orbtk::{
prelude::*,
shell::prelude::{Key, KeyEvent},
theme::{COLORS_RON, FONTS_RON},
theming::config::ThemeConfig,
};
#[cfg(any(feature = "redox", target_os = "redox"))]
use orbtk::theme::REDOX_COLORS_RON;
#[cfg(all(not(feature = "light"), not(feature = "redox")))]
use orbtk::theme::DARK_THEME_RON;
#[cfg(feature = "light")]
use orbtk::theme::LIGHT_THEME_RON;
#[cfg(feature = "redox")]
use orbtk::theme::REDOX_THEME_RON;
use calc;
// --- KEYS --
pub static STYLE_CONTENT: &'static str = "content_area";
pub static STYLE_HEADER: &'static str = "header_area";
pub static STYLE_BUTTON: &'static str = "button_calculator";
pub static STYLE_BUTTON_PRIMARY: &'static str = "button_calculator_primary";
pub static STYLE_INPUT: &'static str = "input";
pub static STYLE_RESULT: &'static str = "result";
static ID_INPUT: &'static str = "input";
// --- KEYS --
// --- THEME --
#[cfg(all(not(feature = "light"), not(feature = "redox")))]
static DARK_EXT: &'static str = include_str!("assets/calculator_dark.ron");
#[cfg(all(not(feature = "light"), not(feature = "redox")))]
fn theme() -> Theme {
Theme::from_config(
ThemeConfig::from(DARK_THEME_RON)
.extend(ThemeConfig::from(DARK_EXT))
.extend(ThemeConfig::from(COLORS_RON))
.extend(ThemeConfig::from(FONTS_RON)),
)
}
#[cfg(all(feature = "light", not(feature = "redox")))]
static LIGHT_EXT: &'static str = include_str!("assets/calculator_light.ron");
#[cfg(all(feature = "light", not(feature = "redox")))]
fn theme() -> Theme {
Theme::from_config(
ThemeConfig::from(LIGHT_THEME_RON)
.extend(ThemeConfig::from(LIGHT_EXT))
.extend(ThemeConfig::from(COLORS_RON))
.extend(ThemeConfig::from(FONTS_RON)),
)
}
#[cfg(any(all(not(feature = "light"), feature = "redox"), target_os = "redox"))]
static REDOX_EXT: &'static str = include_str!("assets/calculator_redox.ron");
#[cfg(any(all(not(feature = "light"), feature = "redox"), target_os = "redox"))]
fn theme() -> Theme {
Theme::from_config(
ThemeConfig::from(REDOX_THEME_RON)
.extend(ThemeConfig::from(REDOX_EXT))
.extend(ThemeConfig::from(COLORS_RON))
.extend(ThemeConfig::from(REDOX_COLORS_RON))
.extend(ThemeConfig::from(FONTS_RON)),
)
}
// --- THEME --
#[derive(Debug, Copy, Clone)]
enum Action {
Character(char),
Operator(char),
Backspace,
}
#[derive(AsAny)]
pub struct MainState {
actions: VecDeque<Action>,
input: Entity,
allowed_signs: Vec<&'static str>,
}
impl Default for MainState {
fn default() -> Self {
MainState {
actions: VecDeque::new(),
allowed_signs: vec![
"(", ")", "^", "/", "*", "-", "+", ".", "0", "1", "2", "3", "4", "5", "6", "7",
"8", "9",
],
input: Entity(0),
}
}
}
impl MainState {
fn action(&mut self, action: Action) {
self.actions.push_back(action);
}
fn key_input(&mut self, event: KeyEvent) {
match event.key {
Key::Enter => {
self.action(Action::Operator('='));
}
Key::Backspace => {
self.action(Action::Backspace);
}
_ => {
if self.allowed_signs.contains(&event.text.as_str()) {
let chars: Vec<char> = event.text.chars().collect();
self.action(Action::Character(*chars.first().unwrap()));
}
}
}
}
fn calculate(&mut self, ctx: &mut Context) {
let result = match calc::eval(
ctx.get_widget(self.input)
.get::<String>("text")
.to_string()
.as_str(),
) {
Ok(s) => s.to_string(),
Err(e) => e.into(),
};
ctx.widget()
.set("text", String::from(format!("{:.9}", result)));
}
}
impl State for MainState {
fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.input = ctx
.entity_of_child(ID_INPUT)
.expect("MainState.init: input child could not be found.");
}
fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
if let Some(action) = self.actions.pop_front() {
match action {
Action::Character(character) => {
ctx.get_widget(self.input)
.get_mut::<String>("text")
.push(character);
}
Action::Operator(operator) => match operator {
'C' => {
ctx.widget().get_mut::<String>("text").clear();
ctx.get_widget(self.input).get_mut::<String>("text").clear()
}
'=' => {
self.calculate(ctx);
ctx.get_widget(self.input).get_mut::<String>("text").clear()
}
_ => {}
},
Action::Backspace => {
let len = ctx.get_widget(self.input).get::<String>("text").len();
if len > 0 {
ctx.get_widget(self.input)
.get_mut::<String>("text")
.remove(len - 1);
}
}
}
}
}
}
fn generate_character_button(
ctx: &mut BuildContext,
id: Entity,
sight: char,
primary: bool,
column: usize,
row: usize,
) -> Entity {
let style = if primary {
STYLE_BUTTON_PRIMARY
} else {
STYLE_BUTTON
};
let button = Button::new()
.style(style)
.min_size(48, 48)
.text(sight.to_string())
.on_click(move |states, _| -> bool {
state(id, states).action(Action::Character(sight));
true
})
.attach(Grid::column(column))
.attach(Grid::row(row));
button.build(ctx)
}
fn generate_operation_button(
ctx: &mut BuildContext,
id: Entity,
sight: char,
primary: bool,
column: usize,
row: usize,
) -> Entity {
let style = if primary {
STYLE_BUTTON_PRIMARY
} else {
STYLE_BUTTON
};
let button = Button::new()
.style(style)
.min_size(48, 48)
.text(sight.to_string())
.on_click(move |states, _| -> bool {
state(id, states).action(Action::Operator(sight));
true
})
.attach(Grid::column(column))
.attach(Grid::row(row));
button.build(ctx)
}
widget!(MainView<MainState> : KeyDownHandler {
text: String
});
impl Template for MainView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
self.name("MainView")
.text("")
.child(
Grid::new()
.rows(Rows::create().push(72).push("*"))
// header
.child(
Container::new()
.style(STYLE_HEADER)
.attach(Grid::row(0))
.padding(8)
.child(
Grid::new()
.child(
ScrollViewer::new()
.mode(("custom", "disabled"))
.child(
TextBlock::new()
.id(ID_INPUT)
.style(STYLE_INPUT)
.width(0)
.height(14)
.text("")
.v_align("start")
.build(ctx),
)
.build(ctx),
)
.child(
TextBlock::new()
.style(STYLE_RESULT)
.text(id)
.v_align("end")
.h_align("end")
.build(ctx),
)
.build(ctx),
)
.build(ctx),
)
// content
.child(
Container::new()
.style(STYLE_CONTENT)
.padding(8)
.attach(Grid::row(1))
.child(
Grid::new()
.columns(
Columns::create()
.push(48)
.push(4)
.push(48)