diff --git a/src/screen/login.rs b/src/screen/login.rs index 9bc0a2a..a515fa1 100644 --- a/src/screen/login.rs +++ b/src/screen/login.rs @@ -1,22 +1,5 @@ - -use std::fs; -use std::thread; -use std::sync::mpsc; -use std::rc::Rc; -use std::cell::RefCell; - use ui; use render; -use format; -use format::{Component, TextComponent}; -use protocol; - -use serde_json; -use time; -use image; -use rustc_serialize::base64::FromBase64; -use rand; -use rand::{Rng}; pub struct Login { elements: Option, @@ -41,6 +24,17 @@ impl super::Screen for Login { let logo = ui::logo::Logo::new(renderer.resources.clone(), renderer, ui_container); let mut elements = ui::Collection::new(); + // Login + let (mut login, mut txt) = super::new_button_text(renderer, "Login", 0.0, 100.0, 400.0, 40.0); + login.set_v_attach(ui::VAttach::Middle); + login.set_h_attach(ui::HAttach::Center); + let re = ui_container.add(login); + txt.set_parent(&re); + let tre = ui_container.add(txt); + super::button_action(ui_container, re.clone(), Some(tre.clone()), None); + elements.add(re); + elements.add(tre); + // Disclaimer let mut warn = ui::Text::new(renderer, "Not affiliated with Mojang/Minecraft", 5.0, 5.0, 255, 200, 200); warn.set_v_attach(ui::VAttach::Bottom); diff --git a/src/ui/batch.rs b/src/ui/batch.rs new file mode 100644 index 0000000..873a4fd --- /dev/null +++ b/src/ui/batch.rs @@ -0,0 +1,96 @@ +#[derive(Clone, Copy)] +pub struct BatchRef { + index: usize, + ty: PhantomData, +} + +ui_element!(Batch { + width: f64, + height: f64, + + elements: Vec +}); + +impl Batch { + base_impl!(); + + pub fn new(x: f64, y: f64, w: f64, h: f64) -> Batch { + ui_create!(Batch { + x: x, + y: y, + width: w, + height: h, + + elements: Vec::new() + }) + } + + fn update(&mut self, _: &mut render::Renderer) {} + + fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, delta: f64) -> &Vec { + if self.dirty { + self.dirty = false; + self.data.clear(); + + let sx = r.w / self.width; + let sy = r.h / self.height; + + for e in &mut self.elements { + let reg = Container::get_draw_region_raw(e, sx, sy, r); + e.set_dirty(true); + self.data.extend(e.draw(renderer, ®, width, height, delta)); + } + } + &self.data + } + + pub fn get_size(&self) -> (f64, f64) { + (self.width, self.height) + } + + pub fn add(&mut self, e: T) -> BatchRef { + self.elements.push(e.wrap()); + BatchRef { index: self.elements.len() - 1, ty: PhantomData } + } + + pub fn get(&self, r: BatchRef) -> &T { + T::unwrap_ref(&self.elements[r.index]) + } + + pub fn get_mut(&mut self, r: BatchRef) -> &mut T { + self.dirty = true; + T::unwrap_ref_mut(&mut self.elements[r.index]) + } + + pub fn get_mut_at(&mut self, index: usize) -> &mut T { + self.dirty = true; + T::unwrap_ref_mut(&mut self.elements[index]) + } + + pub fn len(&self) -> usize { + self.elements.len() + } + + lazy_field!(width, f64, get_width, set_width); + lazy_field!(height, f64, get_height, set_height); +} + +impl UIElement for Batch { + fn wrap(self) -> Element { + Element::Batch(self) + } + + fn unwrap_ref<'a>(e: &'a Element) -> &'a Batch { + match e { + &Element::Batch(ref val) => val, + _ => panic!("Incorrect type"), + } + } + + fn unwrap_ref_mut<'a>(e: &'a mut Element) -> &'a mut Batch { + match e { + &mut Element::Batch(ref mut val) => val, + _ => panic!("Incorrect type"), + } + } +} \ No newline at end of file diff --git a/src/ui/image.rs b/src/ui/image.rs new file mode 100644 index 0000000..2867bf4 --- /dev/null +++ b/src/ui/image.rs @@ -0,0 +1,102 @@ +ui_element!(Image { + texture: render::Texture, + width: f64, + height: f64, + + t_x: f64, + t_y: f64, + t_width: f64, + t_height: f64, + + r: u8, + g: u8, + b: u8, + a: u8 +}); + +impl Image { + base_impl!(); + + pub fn new(texture: render::Texture, x: f64, y: f64, w: f64, h: f64, t_x: f64, t_y: f64, t_width: f64, t_height: f64, r: u8, g: u8, b: u8) -> Image { + ui_create!(Image { + texture: texture, + x: x, + y: y, + width: w, + height: h, + + t_x: t_x, + t_y: t_y, + t_width: t_width, + t_height: t_height, + + r: r, + g: g, + b: b, + a: 255 + }) + } + + fn update(&mut self, _: &mut render::Renderer) {} + + fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, _: f64) -> &Vec { + if self.dirty { + self.dirty = false; + self.texture = renderer.check_texture(self.texture.clone()); + let mut e = render::ui::UIElement::new(&self.texture, r.x, r.y, r.w, r.h, self.t_x, self.t_y, self.t_width, self.t_height); + e.r = self.r; + e.g = self.g; + e.b = self.b; + e.a = self.a; + e.layer = self.layer; + self.data = e.bytes(width, height); + } + &self.data + } + + pub fn get_size(&self) -> (f64, f64) { + (self.width, self.height) + } + + pub fn get_texture(&self) -> render::Texture { + self.texture.clone() + } + + pub fn set_texture(&mut self, val: render::Texture) { + self.texture = val; + self.dirty = true; + } + + lazy_field!(width, f64, get_width, set_width); + lazy_field!(height, f64, get_height, set_height); + + lazy_field!(t_x, f64, get_t_x, set_t_x); + lazy_field!(t_y, f64, get_t_y, set_t_y); + lazy_field!(t_width, f64, get_t_width, set_t_width); + lazy_field!(t_height, f64, get_t_height, set_t_height); + + lazy_field!(r, u8, get_r, set_r); + lazy_field!(g, u8, get_g, set_g); + lazy_field!(b, u8, get_b, set_b); + lazy_field!(a, u8, get_a, set_a); +} + +impl UIElement for Image { + fn wrap(self) -> Element { + Element::Image(self) + } + + fn unwrap_ref<'a>(e: &'a Element) -> &'a Image { + match e { + &Element::Image(ref val) => val, + _ => panic!("Incorrect type"), + } + } + + fn unwrap_ref_mut<'a>(e: &'a mut Element) -> &'a mut Image { + match e { + &mut Element::Image(ref mut val) => val, + _ => panic!("Incorrect type"), + } + } +} \ No newline at end of file diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 0e43e83..03215e2 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -551,312 +551,11 @@ macro_rules! ui_create { ) } -ui_element!(Image { - texture: render::Texture, - width: f64, - height: f64, - - t_x: f64, - t_y: f64, - t_width: f64, - t_height: f64, - - r: u8, - g: u8, - b: u8, - a: u8 -}); - -impl Image { - base_impl!(); - - pub fn new(texture: render::Texture, x: f64, y: f64, w: f64, h: f64, t_x: f64, t_y: f64, t_width: f64, t_height: f64, r: u8, g: u8, b: u8) -> Image { - ui_create!(Image { - texture: texture, - x: x, - y: y, - width: w, - height: h, - - t_x: t_x, - t_y: t_y, - t_width: t_width, - t_height: t_height, - - r: r, - g: g, - b: b, - a: 255 - }) - } - - fn update(&mut self, _: &mut render::Renderer) {} - - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, _: f64) -> &Vec { - if self.dirty { - self.dirty = false; - self.texture = renderer.check_texture(self.texture.clone()); - let mut e = render::ui::UIElement::new(&self.texture, r.x, r.y, r.w, r.h, self.t_x, self.t_y, self.t_width, self.t_height); - e.r = self.r; - e.g = self.g; - e.b = self.b; - e.a = self.a; - e.layer = self.layer; - self.data = e.bytes(width, height); - } - &self.data - } - - pub fn get_size(&self) -> (f64, f64) { - (self.width, self.height) - } - - pub fn get_texture(&self) -> render::Texture { - self.texture.clone() - } - - pub fn set_texture(&mut self, val: render::Texture) { - self.texture = val; - self.dirty = true; - } - - lazy_field!(width, f64, get_width, set_width); - lazy_field!(height, f64, get_height, set_height); - - lazy_field!(t_x, f64, get_t_x, set_t_x); - lazy_field!(t_y, f64, get_t_y, set_t_y); - lazy_field!(t_width, f64, get_t_width, set_t_width); - lazy_field!(t_height, f64, get_t_height, set_t_height); - - lazy_field!(r, u8, get_r, set_r); - lazy_field!(g, u8, get_g, set_g); - lazy_field!(b, u8, get_b, set_b); - lazy_field!(a, u8, get_a, set_a); -} - -impl UIElement for Image { - fn wrap(self) -> Element { - Element::Image(self) - } - - fn unwrap_ref<'a>(e: &'a Element) -> &'a Image { - match e { - &Element::Image(ref val) => val, - _ => panic!("Incorrect type"), - } - } - - fn unwrap_ref_mut<'a>(e: &'a mut Element) -> &'a mut Image { - match e { - &mut Element::Image(ref mut val) => val, - _ => panic!("Incorrect type"), - } - } -} - -#[derive(Clone, Copy)] -pub struct BatchRef { - index: usize, - ty: PhantomData, -} - -ui_element!(Batch { - width: f64, - height: f64, - - elements: Vec -}); - -impl Batch { - base_impl!(); - - pub fn new(x: f64, y: f64, w: f64, h: f64) -> Batch { - ui_create!(Batch { - x: x, - y: y, - width: w, - height: h, - - elements: Vec::new() - }) - } - - fn update(&mut self, _: &mut render::Renderer) {} - - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, delta: f64) -> &Vec { - if self.dirty { - self.dirty = false; - self.data.clear(); - - let sx = r.w / self.width; - let sy = r.h / self.height; - - for e in &mut self.elements { - let reg = Container::get_draw_region_raw(e, sx, sy, r); - e.set_dirty(true); - self.data.extend(e.draw(renderer, ®, width, height, delta)); - } - } - &self.data - } - - pub fn get_size(&self) -> (f64, f64) { - (self.width, self.height) - } - - pub fn add(&mut self, e: T) -> BatchRef { - self.elements.push(e.wrap()); - BatchRef { index: self.elements.len() - 1, ty: PhantomData } - } - - pub fn get(&self, r: BatchRef) -> &T { - T::unwrap_ref(&self.elements[r.index]) - } - - pub fn get_mut(&mut self, r: BatchRef) -> &mut T { - self.dirty = true; - T::unwrap_ref_mut(&mut self.elements[r.index]) - } - - pub fn get_mut_at(&mut self, index: usize) -> &mut T { - self.dirty = true; - T::unwrap_ref_mut(&mut self.elements[index]) - } - - pub fn len(&self) -> usize { - self.elements.len() - } - - lazy_field!(width, f64, get_width, set_width); - lazy_field!(height, f64, get_height, set_height); -} - -impl UIElement for Batch { - fn wrap(self) -> Element { - Element::Batch(self) - } - - fn unwrap_ref<'a>(e: &'a Element) -> &'a Batch { - match e { - &Element::Batch(ref val) => val, - _ => panic!("Incorrect type"), - } - } - - fn unwrap_ref_mut<'a>(e: &'a mut Element) -> &'a mut Batch { - match e { - &mut Element::Batch(ref mut val) => val, - _ => panic!("Incorrect type"), - } - } -} - -ui_element!(Text { - val: String, - width: f64, - height: f64, - scale_x: f64, - scale_y: f64, - rotation: f64, - r: u8, - g: u8, - b: u8, - a: u8 -}); - -impl Text { - base_impl!(); - - pub fn new(renderer: &render::Renderer, val: &str, x: f64, y: f64, r: u8, g: u8, b: u8) -> Text { - ui_create!(Text { - val: val.to_owned(), - x: x, - y: y, - width: renderer.ui.size_of_string(val), - height: 18.0, - scale_x: 1.0, - scale_y: 1.0, - rotation: 0.0, - r: r, - g: g, - b: b, - a: 255 - }) - } - - fn update(&mut self, renderer: &mut render::Renderer) { - self.width = renderer.ui.size_of_string(&self.val); - } - - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, _: f64) -> &Vec { - if self.dirty { - self.dirty = false; - let sx = r.w / self.width; - let sy = r.h / self.height; - let mut text = if self.rotation == 0.0 { - renderer.ui.new_text_scaled(&self.val, r.x, r.y, sx*self.scale_x, sy*self.scale_y, self.r, self.g, self.b) - } else { - let c = self.rotation.cos(); - let s = self.rotation.sin(); - let tmpx = r.w / 2.0; - let tmpy = r.h / 2.0; - let w = (tmpx*c - tmpy*s).abs(); - let h = (tmpy*c + tmpx*s).abs(); - renderer.ui.new_text_rotated(&self.val, r.x+w-(r.w / 2.0), r.y+h-(r.h / 2.0), sx*self.scale_x, sy*self.scale_y, self.rotation, self.r, self.g, self.b) - }; - for e in &mut text.elements { - e.a = self.a; - e.layer = self.layer; - } - self.data = text.bytes(width, height); - } - &self.data - } - - pub fn get_size(&self) -> (f64, f64) { - ((self.width + 2.0) * self.scale_x, self.height * self.scale_y) - } - - pub fn get_text(&self) -> &str { - &self.val - } - - pub fn set_text(&mut self, renderer: &render::Renderer, val: &str) { - self.dirty = true; - self.val = val.to_owned(); - self.width = renderer.ui.size_of_string(val); - } - - lazy_field!(width, f64, get_width, set_width); - lazy_field!(height, f64, get_height, set_height); - lazy_field!(scale_x, f64, get_scale_x, set_scale_x); - lazy_field!(scale_y, f64, get_scale_y, set_scale_y); - lazy_field!(rotation, f64, get_rotation, set_rotation); - lazy_field!(r, u8, get_r, set_r); - lazy_field!(g, u8, get_g, set_g); - lazy_field!(b, u8, get_b, set_b); - -} - -impl UIElement for Text { - fn wrap(self) -> Element { - Element::Text(self) - } - - fn unwrap_ref<'a>(e: &'a Element) -> &'a Text { - match e { - &Element::Text(ref val) => val, - _ => panic!("Incorrect type"), - } - } - - fn unwrap_ref_mut<'a>(e: &'a mut Element) -> &'a mut Text { - match e { - &mut Element::Text(ref mut val) => val, - _ => panic!("Incorrect type"), - } - } -} - -// Include instead of mod so we can access private parts +// Include instead of mod so we can access private parts. +// Its a bit ew doing it this way but it saves us making +// fields public that should be private or having a huge +// file. +include!("image.rs"); +include!("batch.rs"); +include!("text.rs"); include!("formatted.rs"); \ No newline at end of file diff --git a/src/ui/text.rs b/src/ui/text.rs new file mode 100644 index 0000000..cb16a10 --- /dev/null +++ b/src/ui/text.rs @@ -0,0 +1,106 @@ +ui_element!(Text { + val: String, + width: f64, + height: f64, + scale_x: f64, + scale_y: f64, + rotation: f64, + r: u8, + g: u8, + b: u8, + a: u8 +}); + +impl Text { + base_impl!(); + + pub fn new(renderer: &render::Renderer, val: &str, x: f64, y: f64, r: u8, g: u8, b: u8) -> Text { + ui_create!(Text { + val: val.to_owned(), + x: x, + y: y, + width: renderer.ui.size_of_string(val), + height: 18.0, + scale_x: 1.0, + scale_y: 1.0, + rotation: 0.0, + r: r, + g: g, + b: b, + a: 255 + }) + } + + fn update(&mut self, renderer: &mut render::Renderer) { + self.width = renderer.ui.size_of_string(&self.val); + } + + fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, _: f64) -> &Vec { + if self.dirty { + self.dirty = false; + let sx = r.w / self.width; + let sy = r.h / self.height; + let mut text = if self.rotation == 0.0 { + renderer.ui.new_text_scaled(&self.val, r.x, r.y, sx*self.scale_x, sy*self.scale_y, self.r, self.g, self.b) + } else { + let c = self.rotation.cos(); + let s = self.rotation.sin(); + let tmpx = r.w / 2.0; + let tmpy = r.h / 2.0; + let w = (tmpx*c - tmpy*s).abs(); + let h = (tmpy*c + tmpx*s).abs(); + renderer.ui.new_text_rotated(&self.val, r.x+w-(r.w / 2.0), r.y+h-(r.h / 2.0), sx*self.scale_x, sy*self.scale_y, self.rotation, self.r, self.g, self.b) + }; + for e in &mut text.elements { + e.a = self.a; + e.layer = self.layer; + } + self.data = text.bytes(width, height); + } + &self.data + } + + pub fn get_size(&self) -> (f64, f64) { + ((self.width + 2.0) * self.scale_x, self.height * self.scale_y) + } + + pub fn get_text(&self) -> &str { + &self.val + } + + pub fn set_text(&mut self, renderer: &render::Renderer, val: &str) { + self.dirty = true; + self.val = val.to_owned(); + self.width = renderer.ui.size_of_string(val); + } + + lazy_field!(width, f64, get_width, set_width); + lazy_field!(height, f64, get_height, set_height); + lazy_field!(scale_x, f64, get_scale_x, set_scale_x); + lazy_field!(scale_y, f64, get_scale_y, set_scale_y); + lazy_field!(rotation, f64, get_rotation, set_rotation); + lazy_field!(r, u8, get_r, set_r); + lazy_field!(g, u8, get_g, set_g); + lazy_field!(b, u8, get_b, set_b); + +} + +impl UIElement for Text { + fn wrap(self) -> Element { + Element::Text(self) + } + + fn unwrap_ref<'a>(e: &'a Element) -> &'a Text { + match e { + &Element::Text(ref val) => val, + _ => panic!("Incorrect type"), + } + } + + fn unwrap_ref_mut<'a>(e: &'a mut Element) -> &'a mut Text { + match e { + &mut Element::Text(ref mut val) => val, + _ => panic!("Incorrect type"), + } + } +} \ No newline at end of file