[refactor] collect stuff into new mod paint

This commit is contained in:
Emil Ernerfeldt 2020-05-19 22:28:57 +02:00
parent aeaa611005
commit 0f0e385ea3
24 changed files with 212 additions and 190 deletions

View file

@ -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)]
#[serde(default)]
@ -79,7 +84,7 @@ impl State {
}
ui.add_paint_cmd(PaintCmd::Path {
path: mesher::Path::from_point_loop(&points),
path: Path::from_point_loop(&points),
closed: true,
fill_color: None,
outline: Some(Outline::new(stroke_width, stroke_color)),

View file

@ -1,6 +1,6 @@
//! Frame container
use crate::*;
use crate::{paint::*, *};
#[derive(Clone, Debug, Default)]
pub struct Frame {

View file

@ -279,7 +279,7 @@ impl Resize {
if self.outline && corner_interact.is_some() {
let rect = Rect::from_min_size(position, state.size);
let rect = rect.expand(2.0); // breathing room for content
ui.add_paint_cmd(PaintCmd::Rect {
ui.add_paint_cmd(paint::PaintCmd::Rect {
rect,
corner_radius: 3.0,
fill_color: None,
@ -307,7 +307,7 @@ fn paint_resize_corner(ui: &mut Ui, interact: &InteractInfo) {
let mut w = 2.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)],
color,
width,

View file

@ -171,14 +171,14 @@ impl ScrollArea {
let handle_fill_color = style.interact(&handle_interact).fill_color;
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,
corner_radius,
fill_color: Some(outer_ui.style().dark_bg_color),
outline: None,
});
outer_ui.add_paint_cmd(PaintCmd::Rect {
outer_ui.add_paint_cmd(paint::PaintCmd::Rect {
rect: handle_rect.expand(-2.0),
corner_radius,
fill_color: Some(handle_fill_color),

View file

@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc};
use parking_lot::Mutex;
use crate::{layout::align_rect, *};
use crate::{layout::align_rect, paint::*, *};
#[derive(Clone, Copy, Default)]
struct PaintStats {
@ -19,7 +19,7 @@ struct PaintStats {
pub struct Context {
/// The default style for new `Ui`:s
style: Mutex<Style>,
paint_options: Mutex<mesher::PaintOptions>,
paint_options: Mutex<paint::PaintOptions>,
fonts: Arc<Fonts>,
/// HACK: set a new font next frame
new_fonts: Mutex<Option<Arc<Fonts>>>,
@ -116,7 +116,7 @@ impl Context {
&*self.fonts
}
pub fn texture(&self) -> &Texture {
pub fn texture(&self) -> &paint::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::*;
for (text_style, (_family, size)) in font_definitions.iter_mut() {
// 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 {
*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) {
use crate::widgets::*;
ui.add(Checkbox::new(&mut self.anti_alias, "Antialias"));

View 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));
});
}
}
}

View file

@ -2,7 +2,7 @@ use std::collections::HashMap;
use serde_derive::{Deserialize, Serialize};
use crate::{math::Rect, Id, PaintCmd};
use crate::{math::Rect, paint::PaintCmd, Id};
/// Different layer categories
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]

View file

@ -22,40 +22,34 @@
rust_2018_idioms,
)]
pub mod color;
pub mod containers;
mod context;
pub mod examples;
mod font;
mod fonts;
mod id;
mod input;
mod introspection;
mod layers;
mod layout;
pub mod math;
mod memory;
pub mod mesher;
mod movement_tracker;
pub mod paint;
mod style;
mod texture_atlas;
mod types;
mod ui;
pub mod widgets;
pub use {
color::Color,
context::Context,
fonts::{FontDefinitions, Fonts, TextStyle},
id::Id,
input::*,
layers::*,
layout::*,
math::*,
memory::Memory,
mesher::{PaintBatches, Triangles, Vertex},
movement_tracker::MovementTracker,
paint::{color, Color, TextStyle, Texture},
style::Style,
texture_atlas::Texture,
types::*,
ui::Ui,
widgets::Widget,

14
emigui/src/paint.rs Normal file
View 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,
};

View 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(),
}
}
}

View file

@ -3,10 +3,9 @@ use std::{collections::BTreeMap, sync::Arc};
use parking_lot::Mutex;
use rusttype::{point, Scale};
use crate::{
math::{vec2, Vec2},
texture_atlas::TextureAtlas,
};
use crate::math::{vec2, Vec2};
use super::texture_atlas::TextureAtlas;
#[derive(Clone, Copy, Debug, Default)]
pub struct GalleyCursor {

View file

@ -6,7 +6,7 @@ use std::{
use {parking_lot::Mutex, serde_derive::Serialize};
use crate::{
use super::{
font::Font,
texture_atlas::{Texture, TextureAtlas},
};
@ -82,13 +82,13 @@ impl Fonts {
let atlas = Arc::new(Mutex::new(atlas));
// 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.fonts = definitions

View file

@ -1,12 +1,13 @@
#![allow(clippy::identity_op)]
/// Outputs render info in a format suitable for e.g. OpenGL.
use crate::{
color::{self, srgba, Color},
fonts::Fonts,
math::*,
types::PaintCmd,
Outline,
use {
super::{
color::{self, srgba, Color},
fonts::Fonts,
Outline, PaintCmd,
},
crate::math::*,
};
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,
options: PaintOptions,
path_type: PathType,
@ -529,7 +530,7 @@ pub fn paint_command_into_triangles(
fill_closed_path(out, options, &path.0, color);
}
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) => {
@ -541,7 +542,7 @@ pub fn paint_command_into_triangles(
width,
} => {
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 {
points,
@ -551,7 +552,7 @@ pub fn paint_command_into_triangles(
let n = points.len();
if n >= 2 {
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 {
@ -569,7 +570,7 @@ pub fn paint_command_into_triangles(
}
if let Some(outline) = outline {
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 {
@ -588,7 +589,7 @@ pub fn paint_command_into_triangles(
fill_closed_path(out, options, &path.0, fill_color);
}
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 {

View file

@ -89,63 +89,3 @@ impl TextureAtlas {
(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));
});
}
}
}

View file

@ -2,7 +2,7 @@
use serde_derive::{Deserialize, Serialize};
use crate::{color::*, math::*, types::*};
use crate::{color::*, math::*, paint::Outline, types::*};
// TODO: split into Spacing and Style?
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]

View file

@ -1,15 +1,8 @@
use std::sync::Arc;
use serde_derive::{Deserialize, Serialize};
use serde_derive::Serialize;
use crate::{
color::Color,
font::Galley,
fonts::TextStyle,
math::{Pos2, Rect},
mesher::{Path, Triangles},
Context, Ui,
};
use crate::{math::Rect, 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,
}
}
}

View file

@ -1,6 +1,6 @@
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
/// with a type of layout (horizontal or vertical).

View file

@ -5,7 +5,7 @@ use crate::{layout::Direction, GuiResponse, *};
mod slider;
pub mod text_edit;
pub use {slider::*, text_edit::*};
pub use {paint::*, slider::*, text_edit::*};
// ----------------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
use std::ops::RangeInclusive;
use crate::{widgets::Label, *};
use crate::{paint::*, widgets::Label, *};
/// Combined into one function (rather than two) to make it easier
/// for the borrow checker.

View file

@ -1,4 +1,4 @@
use crate::*;
use crate::{paint::*, *};
#[derive(Clone, Copy, Debug, Default, serde_derive::Deserialize, serde_derive::Serialize)]
pub(crate) struct State {

View file

@ -1,7 +1,10 @@
#![allow(deprecated)] // legacy implement_vertex macro
use {
emigui::{PaintBatches, Rect, Triangles},
emigui::{
paint::{PaintBatches, Triangles},
Rect,
},
glium::{implement_vertex, index::PrimitiveType, program, texture, uniform, Frame, Surface},
};

View file

@ -4,7 +4,10 @@ use {
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;

View file

@ -4,7 +4,7 @@
use std::time::{Duration, Instant};
use {
emigui::{examples::ExampleApp, widgets::*, *},
emigui::{examples::ExampleApp, paint::TextStyle, widgets::*, *},
glium::glutin,
};
@ -114,7 +114,7 @@ fn main() {
example_app.ui(&mut ui);
let mut ui = ui.centered_column(ui.available().width().min(480.0));
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 {
running = false;
}