[refactor] collect stuff into new mod paint
This commit is contained in:
parent
aeaa611005
commit
0f0e385ea3
24 changed files with 212 additions and 190 deletions
|
@ -1,4 +1,9 @@
|
||||||
use crate::{layout::Direction, widgets::Label, *};
|
use crate::{
|
||||||
|
layout::Direction,
|
||||||
|
paint::{Outline, PaintCmd, Path, TextStyle},
|
||||||
|
widgets::Label,
|
||||||
|
*,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
|
#[derive(Clone, Copy, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -79,7 +84,7 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.add_paint_cmd(PaintCmd::Path {
|
ui.add_paint_cmd(PaintCmd::Path {
|
||||||
path: mesher::Path::from_point_loop(&points),
|
path: Path::from_point_loop(&points),
|
||||||
closed: true,
|
closed: true,
|
||||||
fill_color: None,
|
fill_color: None,
|
||||||
outline: Some(Outline::new(stroke_width, stroke_color)),
|
outline: Some(Outline::new(stroke_width, stroke_color)),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Frame container
|
//! Frame container
|
||||||
|
|
||||||
use crate::*;
|
use crate::{paint::*, *};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
|
|
|
@ -279,7 +279,7 @@ impl Resize {
|
||||||
if self.outline && corner_interact.is_some() {
|
if self.outline && corner_interact.is_some() {
|
||||||
let rect = Rect::from_min_size(position, state.size);
|
let rect = Rect::from_min_size(position, state.size);
|
||||||
let rect = rect.expand(2.0); // breathing room for content
|
let rect = rect.expand(2.0); // breathing room for content
|
||||||
ui.add_paint_cmd(PaintCmd::Rect {
|
ui.add_paint_cmd(paint::PaintCmd::Rect {
|
||||||
rect,
|
rect,
|
||||||
corner_radius: 3.0,
|
corner_radius: 3.0,
|
||||||
fill_color: None,
|
fill_color: None,
|
||||||
|
@ -307,7 +307,7 @@ fn paint_resize_corner(ui: &mut Ui, interact: &InteractInfo) {
|
||||||
let mut w = 2.0;
|
let mut w = 2.0;
|
||||||
|
|
||||||
while w < 12.0 {
|
while w < 12.0 {
|
||||||
ui.add_paint_cmd(PaintCmd::line_segment(
|
ui.add_paint_cmd(paint::PaintCmd::line_segment(
|
||||||
[pos2(corner.x - w, corner.y), pos2(corner.x, corner.y - w)],
|
[pos2(corner.x - w, corner.y), pos2(corner.x, corner.y - w)],
|
||||||
color,
|
color,
|
||||||
width,
|
width,
|
||||||
|
|
|
@ -171,14 +171,14 @@ impl ScrollArea {
|
||||||
let handle_fill_color = style.interact(&handle_interact).fill_color;
|
let handle_fill_color = style.interact(&handle_interact).fill_color;
|
||||||
let handle_outline = style.interact(&handle_interact).rect_outline;
|
let handle_outline = style.interact(&handle_interact).rect_outline;
|
||||||
|
|
||||||
outer_ui.add_paint_cmd(PaintCmd::Rect {
|
outer_ui.add_paint_cmd(paint::PaintCmd::Rect {
|
||||||
rect: outer_scroll_rect,
|
rect: outer_scroll_rect,
|
||||||
corner_radius,
|
corner_radius,
|
||||||
fill_color: Some(outer_ui.style().dark_bg_color),
|
fill_color: Some(outer_ui.style().dark_bg_color),
|
||||||
outline: None,
|
outline: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
outer_ui.add_paint_cmd(PaintCmd::Rect {
|
outer_ui.add_paint_cmd(paint::PaintCmd::Rect {
|
||||||
rect: handle_rect.expand(-2.0),
|
rect: handle_rect.expand(-2.0),
|
||||||
corner_radius,
|
corner_radius,
|
||||||
fill_color: Some(handle_fill_color),
|
fill_color: Some(handle_fill_color),
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use crate::{layout::align_rect, *};
|
use crate::{layout::align_rect, paint::*, *};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
struct PaintStats {
|
struct PaintStats {
|
||||||
|
@ -19,7 +19,7 @@ struct PaintStats {
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
/// The default style for new `Ui`:s
|
/// The default style for new `Ui`:s
|
||||||
style: Mutex<Style>,
|
style: Mutex<Style>,
|
||||||
paint_options: Mutex<mesher::PaintOptions>,
|
paint_options: Mutex<paint::PaintOptions>,
|
||||||
fonts: Arc<Fonts>,
|
fonts: Arc<Fonts>,
|
||||||
/// HACK: set a new font next frame
|
/// HACK: set a new font next frame
|
||||||
new_fonts: Mutex<Option<Arc<Fonts>>>,
|
new_fonts: Mutex<Option<Arc<Fonts>>>,
|
||||||
|
@ -116,7 +116,7 @@ impl Context {
|
||||||
&*self.fonts
|
&*self.fonts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn texture(&self) -> &Texture {
|
pub fn texture(&self) -> &paint::Texture {
|
||||||
self.fonts().texture()
|
self.fonts().texture()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +581,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn font_definitions_ui(font_definitions: &mut FontDefinitions, ui: &mut Ui) {
|
fn font_definitions_ui(font_definitions: &mut paint::FontDefinitions, ui: &mut Ui) {
|
||||||
use crate::widgets::*;
|
use crate::widgets::*;
|
||||||
for (text_style, (_family, size)) in font_definitions.iter_mut() {
|
for (text_style, (_family, size)) in font_definitions.iter_mut() {
|
||||||
// TODO: radiobutton for family
|
// TODO: radiobutton for family
|
||||||
|
@ -592,7 +592,7 @@ fn font_definitions_ui(font_definitions: &mut FontDefinitions, ui: &mut Ui) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ui.add(Button::new("Reset fonts")).clicked {
|
if ui.add(Button::new("Reset fonts")).clicked {
|
||||||
*font_definitions = crate::fonts::default_font_definitions();
|
*font_definitions = paint::fonts::default_font_definitions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,7 +604,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mesher::PaintOptions {
|
impl paint::PaintOptions {
|
||||||
pub fn ui(&mut self, ui: &mut Ui) {
|
pub fn ui(&mut self, ui: &mut Ui) {
|
||||||
use crate::widgets::*;
|
use crate::widgets::*;
|
||||||
ui.add(Checkbox::new(&mut self.anti_alias, "Antialias"));
|
ui.add(Checkbox::new(&mut self.anti_alias, "Antialias"));
|
||||||
|
|
63
emigui/src/introspection.rs
Normal file
63
emigui/src/introspection.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
//! uis for emigui types.
|
||||||
|
use crate::{
|
||||||
|
containers::show_tooltip,
|
||||||
|
label,
|
||||||
|
math::*,
|
||||||
|
paint::{color::WHITE, PaintCmd, Texture, Triangles, Vertex},
|
||||||
|
};
|
||||||
|
|
||||||
|
impl Texture {
|
||||||
|
pub fn ui(&self, ui: &mut crate::Ui) {
|
||||||
|
ui.add(label!(
|
||||||
|
"Texture size: {} x {} (hover to zoom)",
|
||||||
|
self.width,
|
||||||
|
self.height
|
||||||
|
));
|
||||||
|
let mut size = vec2(self.width as f32, self.height as f32);
|
||||||
|
if size.x > ui.available().width() {
|
||||||
|
size *= ui.available().width() / size.x;
|
||||||
|
}
|
||||||
|
let interact = ui.reserve_space(size, None);
|
||||||
|
let rect = interact.rect;
|
||||||
|
let top_left = Vertex {
|
||||||
|
pos: rect.min,
|
||||||
|
uv: (0, 0),
|
||||||
|
color: WHITE,
|
||||||
|
};
|
||||||
|
let bottom_right = Vertex {
|
||||||
|
pos: rect.max,
|
||||||
|
uv: (self.width as u16 - 1, self.height as u16 - 1),
|
||||||
|
color: WHITE,
|
||||||
|
};
|
||||||
|
let mut triangles = Triangles::default();
|
||||||
|
triangles.add_rect(top_left, bottom_right);
|
||||||
|
ui.add_paint_cmd(PaintCmd::Triangles(triangles));
|
||||||
|
|
||||||
|
if interact.hovered {
|
||||||
|
show_tooltip(ui.ctx(), |ui| {
|
||||||
|
let pos = ui.top_left();
|
||||||
|
let zoom_rect = ui.reserve_space(vec2(128.0, 128.0), None).rect;
|
||||||
|
let u = remap_clamp(pos.x, rect.range_x(), 0.0..=self.width as f32 - 1.0).round();
|
||||||
|
let v = remap_clamp(pos.y, rect.range_y(), 0.0..=self.height as f32 - 1.0).round();
|
||||||
|
|
||||||
|
let texel_radius = 32.0;
|
||||||
|
let u = clamp(u, texel_radius..=self.width as f32 - 1.0 - texel_radius);
|
||||||
|
let v = clamp(v, texel_radius..=self.height as f32 - 1.0 - texel_radius);
|
||||||
|
|
||||||
|
let top_left = Vertex {
|
||||||
|
pos: zoom_rect.min,
|
||||||
|
uv: ((u - texel_radius) as u16, (v - texel_radius) as u16),
|
||||||
|
color: WHITE,
|
||||||
|
};
|
||||||
|
let bottom_right = Vertex {
|
||||||
|
pos: zoom_rect.max,
|
||||||
|
uv: ((u + texel_radius) as u16, (v + texel_radius) as u16),
|
||||||
|
color: WHITE,
|
||||||
|
};
|
||||||
|
let mut triangles = Triangles::default();
|
||||||
|
triangles.add_rect(top_left, bottom_right);
|
||||||
|
ui.add_paint_cmd(PaintCmd::Triangles(triangles));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{math::Rect, Id, PaintCmd};
|
use crate::{math::Rect, paint::PaintCmd, Id};
|
||||||
|
|
||||||
/// Different layer categories
|
/// Different layer categories
|
||||||
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]
|
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]
|
||||||
|
|
|
@ -22,40 +22,34 @@
|
||||||
rust_2018_idioms,
|
rust_2018_idioms,
|
||||||
)]
|
)]
|
||||||
|
|
||||||
pub mod color;
|
|
||||||
pub mod containers;
|
pub mod containers;
|
||||||
mod context;
|
mod context;
|
||||||
pub mod examples;
|
pub mod examples;
|
||||||
mod font;
|
|
||||||
mod fonts;
|
|
||||||
mod id;
|
mod id;
|
||||||
mod input;
|
mod input;
|
||||||
|
mod introspection;
|
||||||
mod layers;
|
mod layers;
|
||||||
mod layout;
|
mod layout;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
mod memory;
|
mod memory;
|
||||||
pub mod mesher;
|
|
||||||
mod movement_tracker;
|
mod movement_tracker;
|
||||||
|
pub mod paint;
|
||||||
mod style;
|
mod style;
|
||||||
mod texture_atlas;
|
|
||||||
mod types;
|
mod types;
|
||||||
mod ui;
|
mod ui;
|
||||||
pub mod widgets;
|
pub mod widgets;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
color::Color,
|
|
||||||
context::Context,
|
context::Context,
|
||||||
fonts::{FontDefinitions, Fonts, TextStyle},
|
|
||||||
id::Id,
|
id::Id,
|
||||||
input::*,
|
input::*,
|
||||||
layers::*,
|
layers::*,
|
||||||
layout::*,
|
layout::*,
|
||||||
math::*,
|
math::*,
|
||||||
memory::Memory,
|
memory::Memory,
|
||||||
mesher::{PaintBatches, Triangles, Vertex},
|
|
||||||
movement_tracker::MovementTracker,
|
movement_tracker::MovementTracker,
|
||||||
|
paint::{color, Color, TextStyle, Texture},
|
||||||
style::Style,
|
style::Style,
|
||||||
texture_atlas::Texture,
|
|
||||||
types::*,
|
types::*,
|
||||||
ui::Ui,
|
ui::Ui,
|
||||||
widgets::Widget,
|
widgets::Widget,
|
||||||
|
|
14
emigui/src/paint.rs
Normal file
14
emigui/src/paint.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
pub mod color;
|
||||||
|
pub mod command;
|
||||||
|
pub mod font;
|
||||||
|
pub mod fonts;
|
||||||
|
pub mod mesher;
|
||||||
|
mod texture_atlas;
|
||||||
|
|
||||||
|
pub use {
|
||||||
|
color::Color,
|
||||||
|
command::{Outline, PaintCmd},
|
||||||
|
fonts::{FontDefinitions, Fonts, TextStyle},
|
||||||
|
mesher::{PaintBatches, PaintOptions, Path, Triangles, Vertex},
|
||||||
|
texture_atlas::Texture,
|
||||||
|
};
|
75
emigui/src/paint/command.rs
Normal file
75
emigui/src/paint/command.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
use {
|
||||||
|
super::{font::Galley, fonts::TextStyle, Color, Path, Triangles},
|
||||||
|
crate::math::{Pos2, Rect},
|
||||||
|
};
|
||||||
|
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
// TODO: rename, e.g. `paint::Cmd`?
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum PaintCmd {
|
||||||
|
Circle {
|
||||||
|
center: Pos2,
|
||||||
|
fill_color: Option<Color>,
|
||||||
|
outline: Option<Outline>,
|
||||||
|
radius: f32,
|
||||||
|
},
|
||||||
|
LineSegment {
|
||||||
|
points: [Pos2; 2],
|
||||||
|
color: Color,
|
||||||
|
width: f32,
|
||||||
|
},
|
||||||
|
// TODO: remove. Just have Path.
|
||||||
|
LinePath {
|
||||||
|
points: Vec<Pos2>,
|
||||||
|
color: Color,
|
||||||
|
width: f32,
|
||||||
|
},
|
||||||
|
Path {
|
||||||
|
path: Path,
|
||||||
|
closed: bool,
|
||||||
|
fill_color: Option<Color>,
|
||||||
|
outline: Option<Outline>,
|
||||||
|
},
|
||||||
|
Rect {
|
||||||
|
rect: Rect,
|
||||||
|
corner_radius: f32,
|
||||||
|
fill_color: Option<Color>,
|
||||||
|
outline: Option<Outline>,
|
||||||
|
},
|
||||||
|
/// Paint a single line of text
|
||||||
|
Text {
|
||||||
|
/// Top left corner of the first character.
|
||||||
|
pos: Pos2,
|
||||||
|
/// The layed out text
|
||||||
|
galley: Galley,
|
||||||
|
text_style: TextStyle, // TODO: Font?
|
||||||
|
color: Color,
|
||||||
|
},
|
||||||
|
Triangles(Triangles),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaintCmd {
|
||||||
|
pub fn line_segment(points: [Pos2; 2], color: Color, width: f32) -> Self {
|
||||||
|
Self::LineSegment {
|
||||||
|
points,
|
||||||
|
color,
|
||||||
|
width,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Outline {
|
||||||
|
pub width: f32,
|
||||||
|
pub color: Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Outline {
|
||||||
|
pub fn new(width: impl Into<f32>, color: impl Into<Color>) -> Self {
|
||||||
|
Self {
|
||||||
|
width: width.into(),
|
||||||
|
color: color.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,10 +3,9 @@ use std::{collections::BTreeMap, sync::Arc};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use rusttype::{point, Scale};
|
use rusttype::{point, Scale};
|
||||||
|
|
||||||
use crate::{
|
use crate::math::{vec2, Vec2};
|
||||||
math::{vec2, Vec2},
|
|
||||||
texture_atlas::TextureAtlas,
|
use super::texture_atlas::TextureAtlas;
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct GalleyCursor {
|
pub struct GalleyCursor {
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
|
|
||||||
use {parking_lot::Mutex, serde_derive::Serialize};
|
use {parking_lot::Mutex, serde_derive::Serialize};
|
||||||
|
|
||||||
use crate::{
|
use super::{
|
||||||
font::Font,
|
font::Font,
|
||||||
texture_atlas::{Texture, TextureAtlas},
|
texture_atlas::{Texture, TextureAtlas},
|
||||||
};
|
};
|
||||||
|
@ -82,13 +82,13 @@ impl Fonts {
|
||||||
let atlas = Arc::new(Mutex::new(atlas));
|
let atlas = Arc::new(Mutex::new(atlas));
|
||||||
|
|
||||||
// TODO: figure out a way to make the wasm smaller despite including a font. Zip it?
|
// TODO: figure out a way to make the wasm smaller despite including a font. Zip it?
|
||||||
let monospae_typeface_data = include_bytes!("../fonts/ProggyClean.ttf"); // Use 13 for this. NOTHING ELSE.
|
let monospae_typeface_data = include_bytes!("../../fonts/ProggyClean.ttf"); // Use 13 for this. NOTHING ELSE.
|
||||||
|
|
||||||
// let monospae_typeface_data = include_bytes!("../fonts/Roboto-Regular.ttf");
|
// let monospae_typeface_data = include_bytes!("../../fonts/Roboto-Regular.ttf");
|
||||||
|
|
||||||
let variable_typeface_data = include_bytes!("../fonts/Comfortaa-Regular.ttf"); // Funny, hard to read
|
let variable_typeface_data = include_bytes!("../../fonts/Comfortaa-Regular.ttf"); // Funny, hard to read
|
||||||
|
|
||||||
// let variable_typeface_data = include_bytes!("../fonts/DejaVuSans.ttf"); // Basic, boring, takes up more space
|
// let variable_typeface_data = include_bytes!("../../fonts/DejaVuSans.ttf"); // Basic, boring, takes up more space
|
||||||
|
|
||||||
self.definitions = definitions.clone();
|
self.definitions = definitions.clone();
|
||||||
self.fonts = definitions
|
self.fonts = definitions
|
|
@ -1,12 +1,13 @@
|
||||||
#![allow(clippy::identity_op)]
|
#![allow(clippy::identity_op)]
|
||||||
|
|
||||||
/// Outputs render info in a format suitable for e.g. OpenGL.
|
/// Outputs render info in a format suitable for e.g. OpenGL.
|
||||||
use crate::{
|
use {
|
||||||
|
super::{
|
||||||
color::{self, srgba, Color},
|
color::{self, srgba, Color},
|
||||||
fonts::Fonts,
|
fonts::Fonts,
|
||||||
math::*,
|
Outline, PaintCmd,
|
||||||
types::PaintCmd,
|
},
|
||||||
Outline,
|
crate::math::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
const WHITE_UV: (u16, u16) = (1, 1);
|
const WHITE_UV: (u16, u16) = (1, 1);
|
||||||
|
@ -338,7 +339,7 @@ pub fn fill_closed_path(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint_path(
|
pub fn paint_path_outline(
|
||||||
triangles: &mut Triangles,
|
triangles: &mut Triangles,
|
||||||
options: PaintOptions,
|
options: PaintOptions,
|
||||||
path_type: PathType,
|
path_type: PathType,
|
||||||
|
@ -529,7 +530,7 @@ pub fn paint_command_into_triangles(
|
||||||
fill_closed_path(out, options, &path.0, color);
|
fill_closed_path(out, options, &path.0, color);
|
||||||
}
|
}
|
||||||
if let Some(outline) = outline {
|
if let Some(outline) = outline {
|
||||||
paint_path(out, options, Closed, &path.0, outline.color, outline.width);
|
paint_path_outline(out, options, Closed, &path.0, outline.color, outline.width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Triangles(triangles) => {
|
PaintCmd::Triangles(triangles) => {
|
||||||
|
@ -541,7 +542,7 @@ pub fn paint_command_into_triangles(
|
||||||
width,
|
width,
|
||||||
} => {
|
} => {
|
||||||
path.add_line_segment(points);
|
path.add_line_segment(points);
|
||||||
paint_path(out, options, Open, &path.0, color, width);
|
paint_path_outline(out, options, Open, &path.0, color, width);
|
||||||
}
|
}
|
||||||
PaintCmd::LinePath {
|
PaintCmd::LinePath {
|
||||||
points,
|
points,
|
||||||
|
@ -551,7 +552,7 @@ pub fn paint_command_into_triangles(
|
||||||
let n = points.len();
|
let n = points.len();
|
||||||
if n >= 2 {
|
if n >= 2 {
|
||||||
path.add_line(&points);
|
path.add_line(&points);
|
||||||
paint_path(out, options, Open, &path.0, color, width);
|
paint_path_outline(out, options, Open, &path.0, color, width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Path {
|
PaintCmd::Path {
|
||||||
|
@ -569,7 +570,7 @@ pub fn paint_command_into_triangles(
|
||||||
}
|
}
|
||||||
if let Some(outline) = outline {
|
if let Some(outline) = outline {
|
||||||
let typ = if closed { Closed } else { Open };
|
let typ = if closed { Closed } else { Open };
|
||||||
paint_path(out, options, typ, &path.0, outline.color, outline.width);
|
paint_path_outline(out, options, typ, &path.0, outline.color, outline.width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Rect {
|
PaintCmd::Rect {
|
||||||
|
@ -588,7 +589,7 @@ pub fn paint_command_into_triangles(
|
||||||
fill_closed_path(out, options, &path.0, fill_color);
|
fill_closed_path(out, options, &path.0, fill_color);
|
||||||
}
|
}
|
||||||
if let Some(outline) = outline {
|
if let Some(outline) = outline {
|
||||||
paint_path(out, options, Closed, &path.0, outline.color, outline.width);
|
paint_path_outline(out, options, Closed, &path.0, outline.color, outline.width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Text {
|
PaintCmd::Text {
|
|
@ -89,63 +89,3 @@ impl TextureAtlas {
|
||||||
(pos.0 as usize, pos.1 as usize)
|
(pos.0 as usize, pos.1 as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Texture {
|
|
||||||
pub fn ui(&self, ui: &mut crate::Ui) {
|
|
||||||
use crate::{
|
|
||||||
color::WHITE, containers::show_tooltip, label, math::*, PaintCmd, Triangles, Vertex,
|
|
||||||
};
|
|
||||||
|
|
||||||
ui.add(label!(
|
|
||||||
"Texture size: {} x {} (hover to zoom)",
|
|
||||||
self.width,
|
|
||||||
self.height
|
|
||||||
));
|
|
||||||
let mut size = vec2(self.width as f32, self.height as f32);
|
|
||||||
if size.x > ui.available().width() {
|
|
||||||
size *= ui.available().width() / size.x;
|
|
||||||
}
|
|
||||||
let interact = ui.reserve_space(size, None);
|
|
||||||
let rect = interact.rect;
|
|
||||||
let top_left = Vertex {
|
|
||||||
pos: rect.min,
|
|
||||||
uv: (0, 0),
|
|
||||||
color: WHITE,
|
|
||||||
};
|
|
||||||
let bottom_right = Vertex {
|
|
||||||
pos: rect.max,
|
|
||||||
uv: (self.width as u16 - 1, self.height as u16 - 1),
|
|
||||||
color: WHITE,
|
|
||||||
};
|
|
||||||
let mut triangles = Triangles::default();
|
|
||||||
triangles.add_rect(top_left, bottom_right);
|
|
||||||
ui.add_paint_cmd(PaintCmd::Triangles(triangles));
|
|
||||||
|
|
||||||
if interact.hovered {
|
|
||||||
show_tooltip(ui.ctx(), |ui| {
|
|
||||||
let pos = ui.top_left();
|
|
||||||
let zoom_rect = ui.reserve_space(vec2(128.0, 128.0), None).rect;
|
|
||||||
let u = remap_clamp(pos.x, rect.range_x(), 0.0..=self.width as f32 - 1.0).round();
|
|
||||||
let v = remap_clamp(pos.y, rect.range_y(), 0.0..=self.height as f32 - 1.0).round();
|
|
||||||
|
|
||||||
let texel_radius = 32.0;
|
|
||||||
let u = clamp(u, texel_radius..=self.width as f32 - 1.0 - texel_radius);
|
|
||||||
let v = clamp(v, texel_radius..=self.height as f32 - 1.0 - texel_radius);
|
|
||||||
|
|
||||||
let top_left = Vertex {
|
|
||||||
pos: zoom_rect.min,
|
|
||||||
uv: ((u - texel_radius) as u16, (v - texel_radius) as u16),
|
|
||||||
color: WHITE,
|
|
||||||
};
|
|
||||||
let bottom_right = Vertex {
|
|
||||||
pos: zoom_rect.max,
|
|
||||||
uv: ((u + texel_radius) as u16, (v + texel_radius) as u16),
|
|
||||||
color: WHITE,
|
|
||||||
};
|
|
||||||
let mut triangles = Triangles::default();
|
|
||||||
triangles.add_rect(top_left, bottom_right);
|
|
||||||
ui.add_paint_cmd(PaintCmd::Triangles(triangles));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{color::*, math::*, types::*};
|
use crate::{color::*, math::*, paint::Outline, types::*};
|
||||||
|
|
||||||
// TODO: split into Spacing and Style?
|
// TODO: split into Spacing and Style?
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
|
|
|
@ -1,15 +1,8 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{math::Rect, Context, Ui};
|
||||||
color::Color,
|
|
||||||
font::Galley,
|
|
||||||
fonts::TextStyle,
|
|
||||||
math::{Pos2, Rect},
|
|
||||||
mesher::{Path, Triangles},
|
|
||||||
Context, Ui,
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -118,71 +111,3 @@ impl GuiResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
|
||||||
pub struct Outline {
|
|
||||||
pub width: f32,
|
|
||||||
pub color: Color,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Outline {
|
|
||||||
pub fn new(width: impl Into<f32>, color: impl Into<Color>) -> Self {
|
|
||||||
Self {
|
|
||||||
width: width.into(),
|
|
||||||
color: color.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum PaintCmd {
|
|
||||||
Circle {
|
|
||||||
center: Pos2,
|
|
||||||
fill_color: Option<Color>,
|
|
||||||
outline: Option<Outline>,
|
|
||||||
radius: f32,
|
|
||||||
},
|
|
||||||
LineSegment {
|
|
||||||
points: [Pos2; 2],
|
|
||||||
color: Color,
|
|
||||||
width: f32,
|
|
||||||
},
|
|
||||||
// TODO: remove. Just have Path.
|
|
||||||
LinePath {
|
|
||||||
points: Vec<Pos2>,
|
|
||||||
color: Color,
|
|
||||||
width: f32,
|
|
||||||
},
|
|
||||||
Path {
|
|
||||||
path: Path,
|
|
||||||
closed: bool,
|
|
||||||
fill_color: Option<Color>,
|
|
||||||
outline: Option<Outline>,
|
|
||||||
},
|
|
||||||
Rect {
|
|
||||||
rect: Rect,
|
|
||||||
corner_radius: f32,
|
|
||||||
fill_color: Option<Color>,
|
|
||||||
outline: Option<Outline>,
|
|
||||||
},
|
|
||||||
/// Paint a single line of text
|
|
||||||
Text {
|
|
||||||
/// Top left corner of the first character.
|
|
||||||
pos: Pos2,
|
|
||||||
/// The layed out text
|
|
||||||
galley: Galley,
|
|
||||||
text_style: TextStyle, // TODO: Font?
|
|
||||||
color: Color,
|
|
||||||
},
|
|
||||||
Triangles(Triangles),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PaintCmd {
|
|
||||||
pub fn line_segment(points: [Pos2; 2], color: Color, width: f32) -> Self {
|
|
||||||
Self::LineSegment {
|
|
||||||
points,
|
|
||||||
color,
|
|
||||||
width,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{hash::Hash, sync::Arc};
|
use std::{hash::Hash, sync::Arc};
|
||||||
|
|
||||||
use crate::{color::*, containers::*, layout::*, widgets::*, *};
|
use crate::{color::*, containers::*, layout::*, paint::*, widgets::*, *};
|
||||||
|
|
||||||
/// Represents a region of the screen
|
/// Represents a region of the screen
|
||||||
/// with a type of layout (horizontal or vertical).
|
/// with a type of layout (horizontal or vertical).
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{layout::Direction, GuiResponse, *};
|
||||||
mod slider;
|
mod slider;
|
||||||
pub mod text_edit;
|
pub mod text_edit;
|
||||||
|
|
||||||
pub use {slider::*, text_edit::*};
|
pub use {paint::*, slider::*, text_edit::*};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
use crate::{widgets::Label, *};
|
use crate::{paint::*, widgets::Label, *};
|
||||||
|
|
||||||
/// Combined into one function (rather than two) to make it easier
|
/// Combined into one function (rather than two) to make it easier
|
||||||
/// for the borrow checker.
|
/// for the borrow checker.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::*;
|
use crate::{paint::*, *};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, serde_derive::Deserialize, serde_derive::Serialize)]
|
#[derive(Clone, Copy, Debug, Default, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#![allow(deprecated)] // legacy implement_vertex macro
|
#![allow(deprecated)] // legacy implement_vertex macro
|
||||||
|
|
||||||
use {
|
use {
|
||||||
emigui::{PaintBatches, Rect, Triangles},
|
emigui::{
|
||||||
|
paint::{PaintBatches, Triangles},
|
||||||
|
Rect,
|
||||||
|
},
|
||||||
glium::{implement_vertex, index::PrimitiveType, program, texture, uniform, Frame, Surface},
|
glium::{implement_vertex, index::PrimitiveType, program, texture, uniform, Frame, Surface},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@ use {
|
||||||
web_sys::{WebGlBuffer, WebGlProgram, WebGlRenderingContext, WebGlShader, WebGlTexture},
|
web_sys::{WebGlBuffer, WebGlProgram, WebGlRenderingContext, WebGlShader, WebGlTexture},
|
||||||
};
|
};
|
||||||
|
|
||||||
use emigui::{vec2, Color, PaintBatches, Pos2, Texture, Triangles};
|
use emigui::{
|
||||||
|
paint::{Color, PaintBatches, Texture, Triangles},
|
||||||
|
vec2, Pos2,
|
||||||
|
};
|
||||||
|
|
||||||
type Gl = WebGlRenderingContext;
|
type Gl = WebGlRenderingContext;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
emigui::{examples::ExampleApp, widgets::*, *},
|
emigui::{examples::ExampleApp, paint::TextStyle, widgets::*, *},
|
||||||
glium::glutin,
|
glium::glutin,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ fn main() {
|
||||||
example_app.ui(&mut ui);
|
example_app.ui(&mut ui);
|
||||||
let mut ui = ui.centered_column(ui.available().width().min(480.0));
|
let mut ui = ui.centered_column(ui.available().width().min(480.0));
|
||||||
ui.set_layout(Layout::vertical(Align::Min));
|
ui.set_layout(Layout::vertical(Align::Min));
|
||||||
ui.add(label!("Emigui running inside of Glium").text_style(emigui::TextStyle::Heading));
|
ui.add(label!("Emigui running inside of Glium").text_style(TextStyle::Heading));
|
||||||
if ui.add(Button::new("Quit")).clicked {
|
if ui.add(Button::new("Quit")).clicked {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue