mirror of https://codeberg.org/topola/topola.git
egui: move viewport to its own file
This commit is contained in:
parent
ce1a070a70
commit
6d66558a72
|
|
@ -40,7 +40,7 @@ use topola::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{layers::Layers, overlay::Overlay, painter::Painter, top::Top};
|
use crate::{layers::Layers, overlay::Overlay, painter::Painter, top::Top, viewport::Viewport};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct SharedData {
|
pub struct SharedData {
|
||||||
|
|
@ -69,7 +69,7 @@ pub struct App {
|
||||||
text_channel: (Sender<String>, Receiver<String>),
|
text_channel: (Sender<String>, Receiver<String>),
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
from_rect: egui::emath::Rect,
|
viewport: Viewport,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
top: Top,
|
top: Top,
|
||||||
|
|
@ -85,7 +85,7 @@ impl Default for App {
|
||||||
invoker: None,
|
invoker: None,
|
||||||
shared_data: Default::default(),
|
shared_data: Default::default(),
|
||||||
text_channel: channel(),
|
text_channel: channel(),
|
||||||
from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0),
|
viewport: Viewport::new(),
|
||||||
top: Top::new(),
|
top: Top::new(),
|
||||||
layers: None,
|
layers: None,
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +189,7 @@ impl eframe::App for App {
|
||||||
self.shared_data.clone(),
|
self.shared_data.clone(),
|
||||||
self.text_channel.0.clone(),
|
self.text_channel.0.clone(),
|
||||||
&self.invoker,
|
&self.invoker,
|
||||||
&self.overlay,
|
&mut self.overlay,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(ref mut layers) = self.layers {
|
if let Some(ref mut layers) = self.layers {
|
||||||
|
|
@ -198,217 +198,13 @@ impl eframe::App for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
self.viewport.update(
|
||||||
egui::Frame::canvas(ui.style()).show(ui, |ui| {
|
ctx,
|
||||||
ui.ctx().request_repaint();
|
&self.top,
|
||||||
|
self.shared_data.clone(),
|
||||||
let desired_size = ui.available_width() * egui::vec2(1.0, 0.5);
|
&self.invoker,
|
||||||
let (_id, viewport_rect) = ui.allocate_space(desired_size);
|
|
||||||
|
|
||||||
let old_transform =
|
|
||||||
egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
|
|
||||||
let latest_pos = old_transform
|
|
||||||
.inverse()
|
|
||||||
.transform_pos(ctx.input(|i| i.pointer.latest_pos().unwrap_or_default()));
|
|
||||||
|
|
||||||
let old_scale = old_transform.scale().x;
|
|
||||||
self.from_rect = self.from_rect / ctx.input(|i| i.zoom_delta());
|
|
||||||
|
|
||||||
let new_scale = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect)
|
|
||||||
.scale()
|
|
||||||
.x;
|
|
||||||
|
|
||||||
self.from_rect = self.from_rect.translate(
|
|
||||||
ctx.input(|i| latest_pos.to_vec2() * (new_scale - old_scale) / new_scale),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.from_rect = self
|
|
||||||
.from_rect
|
|
||||||
.translate(ctx.input(|i| -i.raw_scroll_delta / new_scale));
|
|
||||||
|
|
||||||
let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
|
|
||||||
let mut painter = Painter::new(ui, transform);
|
|
||||||
|
|
||||||
if let Some(invoker_arc_mutex) = &self.invoker {
|
|
||||||
if ctx.input(|i| i.pointer.any_click()) {
|
|
||||||
if self.top.is_placing_via {
|
|
||||||
let invoker_arc_mutex = invoker_arc_mutex.clone();
|
|
||||||
|
|
||||||
execute(async move {
|
|
||||||
let mut invoker = invoker_arc_mutex.lock().unwrap();
|
|
||||||
invoker.execute(
|
|
||||||
Command::PlaceVia(ViaWeight {
|
|
||||||
from_layer: 0,
|
|
||||||
to_layer: 0,
|
|
||||||
circle: Circle {
|
|
||||||
pos: point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
|
||||||
r: 10000.0,
|
|
||||||
},
|
|
||||||
maybe_net: Some(1234),
|
|
||||||
}),
|
|
||||||
&mut EmptyRouterObserver,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else if let Some(overlay) = &mut self.overlay {
|
|
||||||
let invoker = invoker_arc_mutex.lock().unwrap();
|
|
||||||
overlay.click(
|
|
||||||
invoker.autorouter().board(),
|
|
||||||
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (invoker, shared_data, Some(overlay)) = (
|
|
||||||
&invoker_arc_mutex.lock().unwrap(),
|
|
||||||
self.shared_data.lock().unwrap(),
|
|
||||||
&mut self.overlay,
|
&mut self.overlay,
|
||||||
) {
|
|
||||||
let board = invoker.autorouter().board();
|
|
||||||
|
|
||||||
for primitive in board.layout().drawing().layer_primitive_nodes(1) {
|
|
||||||
let shape = primitive.primitive(board.layout().drawing()).shape();
|
|
||||||
|
|
||||||
let color = if shared_data.highlighteds.contains(&primitive)
|
|
||||||
|| overlay
|
|
||||||
.selection()
|
|
||||||
.contains_node(board, GenericNode::Primitive(primitive))
|
|
||||||
{
|
|
||||||
egui::Color32::from_rgb(100, 100, 255)
|
|
||||||
} else {
|
|
||||||
egui::Color32::from_rgb(52, 52, 200)
|
|
||||||
};
|
|
||||||
painter.paint_primitive(&shape, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
for zone in board.layout().layer_zone_nodes(1) {
|
|
||||||
let color = if overlay
|
|
||||||
.selection()
|
|
||||||
.contains_node(board, GenericNode::Compound(zone.into()))
|
|
||||||
{
|
|
||||||
egui::Color32::from_rgb(100, 100, 255)
|
|
||||||
} else {
|
|
||||||
egui::Color32::from_rgb(52, 52, 200)
|
|
||||||
};
|
|
||||||
painter.paint_polygon(&board.layout().zone(zone).shape().polygon, color)
|
|
||||||
}
|
|
||||||
|
|
||||||
for primitive in board.layout().drawing().layer_primitive_nodes(0) {
|
|
||||||
let shape = primitive.primitive(board.layout().drawing()).shape();
|
|
||||||
|
|
||||||
let color = if shared_data.highlighteds.contains(&primitive)
|
|
||||||
|| overlay
|
|
||||||
.selection()
|
|
||||||
.contains_node(board, GenericNode::Primitive(primitive))
|
|
||||||
{
|
|
||||||
egui::Color32::from_rgb(255, 100, 100)
|
|
||||||
} else {
|
|
||||||
egui::Color32::from_rgb(200, 52, 52)
|
|
||||||
};
|
|
||||||
painter.paint_primitive(&shape, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
for zone in board.layout().layer_zone_nodes(0) {
|
|
||||||
let color = if overlay
|
|
||||||
.selection()
|
|
||||||
.contains_node(board, GenericNode::Compound(zone.into()))
|
|
||||||
{
|
|
||||||
egui::Color32::from_rgb(255, 100, 100)
|
|
||||||
} else {
|
|
||||||
egui::Color32::from_rgb(200, 52, 52)
|
|
||||||
};
|
|
||||||
painter.paint_polygon(&board.layout().zone(zone).shape().polygon, color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.top.show_ratsnest {
|
|
||||||
for edge in overlay.ratsnest().graph().edge_references() {
|
|
||||||
let from = overlay
|
|
||||||
.ratsnest()
|
|
||||||
.graph()
|
|
||||||
.node_weight(edge.source())
|
|
||||||
.unwrap()
|
|
||||||
.pos;
|
|
||||||
let to = overlay
|
|
||||||
.ratsnest()
|
|
||||||
.graph()
|
|
||||||
.node_weight(edge.target())
|
|
||||||
.unwrap()
|
|
||||||
.pos;
|
|
||||||
|
|
||||||
painter.paint_edge(
|
|
||||||
from,
|
|
||||||
to,
|
|
||||||
egui::Stroke::new(1.0, egui::Color32::from_rgb(90, 90, 200)),
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(navmesh) = &shared_data.navmesh {
|
|
||||||
for edge in navmesh.edge_references() {
|
|
||||||
let from = edge
|
|
||||||
.source()
|
|
||||||
.primitive(board.layout().drawing())
|
|
||||||
.shape()
|
|
||||||
.center();
|
|
||||||
let to = edge
|
|
||||||
.target()
|
|
||||||
.primitive(board.layout().drawing())
|
|
||||||
.shape()
|
|
||||||
.center();
|
|
||||||
|
|
||||||
let stroke = 'blk: {
|
|
||||||
if let (Some(source_pos), Some(target_pos)) = (
|
|
||||||
shared_data
|
|
||||||
.path
|
|
||||||
.iter()
|
|
||||||
.position(|node| *node == edge.source()),
|
|
||||||
shared_data
|
|
||||||
.path
|
|
||||||
.iter()
|
|
||||||
.position(|node| *node == edge.target()),
|
|
||||||
) {
|
|
||||||
if target_pos == source_pos + 1
|
|
||||||
|| source_pos == target_pos + 1
|
|
||||||
{
|
|
||||||
break 'blk egui::Stroke::new(
|
|
||||||
5.0,
|
|
||||||
egui::Color32::from_rgb(250, 250, 0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
egui::Stroke::new(1.0, egui::Color32::from_rgb(125, 125, 125))
|
|
||||||
};
|
|
||||||
|
|
||||||
painter.paint_edge(from, to, stroke);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ghost in shared_data.ghosts.iter() {
|
|
||||||
painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (Some(from), Some(to)) = (shared_data.from, shared_data.to) {
|
|
||||||
painter.paint_dot(
|
|
||||||
Circle {
|
|
||||||
pos: board.layout().drawing().primitive(from).shape().center(),
|
|
||||||
r: 20.0,
|
|
||||||
},
|
|
||||||
egui::Color32::from_rgb(255, 255, 100),
|
|
||||||
);
|
|
||||||
painter.paint_dot(
|
|
||||||
Circle {
|
|
||||||
pos: board.layout().drawing().primitive(to).shape().center(),
|
|
||||||
r: 20.0,
|
|
||||||
},
|
|
||||||
egui::Color32::from_rgb(255, 255, 100),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//unreachable!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if ctx.input(|i| i.key_pressed(egui::Key::Escape)) {
|
if ctx.input(|i| i.key_pressed(egui::Key::Escape)) {
|
||||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ mod layers;
|
||||||
mod overlay;
|
mod overlay;
|
||||||
mod painter;
|
mod painter;
|
||||||
mod top;
|
mod top;
|
||||||
|
mod viewport;
|
||||||
use app::App;
|
use app::App;
|
||||||
|
|
||||||
// Build to native.
|
// Build to native.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,254 @@
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use geo::point;
|
||||||
|
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||||
|
use topola::{
|
||||||
|
autorouter::invoker::{Command, Invoker},
|
||||||
|
board::mesadata::MesadataTrait,
|
||||||
|
drawing::{graph::MakePrimitive, primitive::MakePrimitiveShape},
|
||||||
|
dsn::mesadata::DsnMesadata,
|
||||||
|
geometry::{shape::ShapeTrait, GenericNode},
|
||||||
|
layout::{via::ViaWeight, zone::MakePolyShape},
|
||||||
|
math::Circle,
|
||||||
|
router::EmptyRouterObserver,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
app::{execute, SharedData},
|
||||||
|
overlay::Overlay,
|
||||||
|
painter::Painter,
|
||||||
|
top::Top,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Viewport {
|
||||||
|
from_rect: egui::emath::Rect,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Viewport {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
|
ctx: &egui::Context,
|
||||||
|
top: &Top,
|
||||||
|
shared_data: Arc<Mutex<SharedData>>,
|
||||||
|
maybe_invoker: &Option<Arc<Mutex<Invoker<DsnMesadata>>>>,
|
||||||
|
maybe_overlay: &mut Option<Overlay>,
|
||||||
|
) {
|
||||||
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
|
egui::Frame::canvas(ui.style()).show(ui, |ui| {
|
||||||
|
ui.ctx().request_repaint();
|
||||||
|
|
||||||
|
let desired_size = ui.available_width() * egui::vec2(1.0, 0.5);
|
||||||
|
let (_id, viewport_rect) = ui.allocate_space(desired_size);
|
||||||
|
|
||||||
|
let old_transform =
|
||||||
|
egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
|
||||||
|
let latest_pos = old_transform
|
||||||
|
.inverse()
|
||||||
|
.transform_pos(ctx.input(|i| i.pointer.latest_pos().unwrap_or_default()));
|
||||||
|
|
||||||
|
let old_scale = old_transform.scale().x;
|
||||||
|
self.from_rect = self.from_rect / ctx.input(|i| i.zoom_delta());
|
||||||
|
|
||||||
|
let new_scale = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect)
|
||||||
|
.scale()
|
||||||
|
.x;
|
||||||
|
|
||||||
|
self.from_rect = self.from_rect.translate(
|
||||||
|
ctx.input(|i| latest_pos.to_vec2() * (new_scale - old_scale) / new_scale),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.from_rect = self
|
||||||
|
.from_rect
|
||||||
|
.translate(ctx.input(|i| -i.raw_scroll_delta / new_scale));
|
||||||
|
|
||||||
|
let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
|
||||||
|
let mut painter = Painter::new(ui, transform);
|
||||||
|
|
||||||
|
if let Some(invoker_arc_mutex) = maybe_invoker {
|
||||||
|
if ctx.input(|i| i.pointer.any_click()) {
|
||||||
|
if top.is_placing_via {
|
||||||
|
let invoker_arc_mutex = invoker_arc_mutex.clone();
|
||||||
|
|
||||||
|
execute(async move {
|
||||||
|
let mut invoker = invoker_arc_mutex.lock().unwrap();
|
||||||
|
invoker.execute(
|
||||||
|
Command::PlaceVia(ViaWeight {
|
||||||
|
from_layer: 0,
|
||||||
|
to_layer: 0,
|
||||||
|
circle: Circle {
|
||||||
|
pos: point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
||||||
|
r: 10000.0,
|
||||||
|
},
|
||||||
|
maybe_net: Some(1234),
|
||||||
|
}),
|
||||||
|
&mut EmptyRouterObserver,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else if let Some(overlay) = maybe_overlay {
|
||||||
|
let invoker = invoker_arc_mutex.lock().unwrap();
|
||||||
|
overlay.click(
|
||||||
|
invoker.autorouter().board(),
|
||||||
|
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let (invoker, shared_data, Some(overlay)) = (
|
||||||
|
&invoker_arc_mutex.lock().unwrap(),
|
||||||
|
shared_data.lock().unwrap(),
|
||||||
|
maybe_overlay,
|
||||||
|
) {
|
||||||
|
let board = invoker.autorouter().board();
|
||||||
|
|
||||||
|
for primitive in board.layout().drawing().layer_primitive_nodes(1) {
|
||||||
|
let shape = primitive.primitive(board.layout().drawing()).shape();
|
||||||
|
|
||||||
|
let color = if shared_data.highlighteds.contains(&primitive)
|
||||||
|
|| overlay
|
||||||
|
.selection()
|
||||||
|
.contains_node(board, GenericNode::Primitive(primitive))
|
||||||
|
{
|
||||||
|
egui::Color32::from_rgb(100, 100, 255)
|
||||||
|
} else {
|
||||||
|
egui::Color32::from_rgb(52, 52, 200)
|
||||||
|
};
|
||||||
|
painter.paint_primitive(&shape, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
for zone in board.layout().layer_zone_nodes(1) {
|
||||||
|
let color = if overlay
|
||||||
|
.selection()
|
||||||
|
.contains_node(board, GenericNode::Compound(zone.into()))
|
||||||
|
{
|
||||||
|
egui::Color32::from_rgb(100, 100, 255)
|
||||||
|
} else {
|
||||||
|
egui::Color32::from_rgb(52, 52, 200)
|
||||||
|
};
|
||||||
|
painter.paint_polygon(&board.layout().zone(zone).shape().polygon, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
for primitive in board.layout().drawing().layer_primitive_nodes(0) {
|
||||||
|
let shape = primitive.primitive(board.layout().drawing()).shape();
|
||||||
|
|
||||||
|
let color = if shared_data.highlighteds.contains(&primitive)
|
||||||
|
|| overlay
|
||||||
|
.selection()
|
||||||
|
.contains_node(board, GenericNode::Primitive(primitive))
|
||||||
|
{
|
||||||
|
egui::Color32::from_rgb(255, 100, 100)
|
||||||
|
} else {
|
||||||
|
egui::Color32::from_rgb(200, 52, 52)
|
||||||
|
};
|
||||||
|
painter.paint_primitive(&shape, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
for zone in board.layout().layer_zone_nodes(0) {
|
||||||
|
let color = if overlay
|
||||||
|
.selection()
|
||||||
|
.contains_node(board, GenericNode::Compound(zone.into()))
|
||||||
|
{
|
||||||
|
egui::Color32::from_rgb(255, 100, 100)
|
||||||
|
} else {
|
||||||
|
egui::Color32::from_rgb(200, 52, 52)
|
||||||
|
};
|
||||||
|
painter.paint_polygon(&board.layout().zone(zone).shape().polygon, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
if top.show_ratsnest {
|
||||||
|
for edge in overlay.ratsnest().graph().edge_references() {
|
||||||
|
let from = overlay
|
||||||
|
.ratsnest()
|
||||||
|
.graph()
|
||||||
|
.node_weight(edge.source())
|
||||||
|
.unwrap()
|
||||||
|
.pos;
|
||||||
|
let to = overlay
|
||||||
|
.ratsnest()
|
||||||
|
.graph()
|
||||||
|
.node_weight(edge.target())
|
||||||
|
.unwrap()
|
||||||
|
.pos;
|
||||||
|
|
||||||
|
painter.paint_edge(
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
egui::Stroke::new(1.0, egui::Color32::from_rgb(90, 90, 200)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(navmesh) = &shared_data.navmesh {
|
||||||
|
for edge in navmesh.edge_references() {
|
||||||
|
let from = edge
|
||||||
|
.source()
|
||||||
|
.primitive(board.layout().drawing())
|
||||||
|
.shape()
|
||||||
|
.center();
|
||||||
|
let to = edge
|
||||||
|
.target()
|
||||||
|
.primitive(board.layout().drawing())
|
||||||
|
.shape()
|
||||||
|
.center();
|
||||||
|
|
||||||
|
let stroke = 'blk: {
|
||||||
|
if let (Some(source_pos), Some(target_pos)) = (
|
||||||
|
shared_data
|
||||||
|
.path
|
||||||
|
.iter()
|
||||||
|
.position(|node| *node == edge.source()),
|
||||||
|
shared_data
|
||||||
|
.path
|
||||||
|
.iter()
|
||||||
|
.position(|node| *node == edge.target()),
|
||||||
|
) {
|
||||||
|
if target_pos == source_pos + 1
|
||||||
|
|| source_pos == target_pos + 1
|
||||||
|
{
|
||||||
|
break 'blk egui::Stroke::new(
|
||||||
|
5.0,
|
||||||
|
egui::Color32::from_rgb(250, 250, 0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
egui::Stroke::new(1.0, egui::Color32::from_rgb(125, 125, 125))
|
||||||
|
};
|
||||||
|
|
||||||
|
painter.paint_edge(from, to, stroke);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ghost in shared_data.ghosts.iter() {
|
||||||
|
painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let (Some(from), Some(to)) = (shared_data.from, shared_data.to) {
|
||||||
|
painter.paint_dot(
|
||||||
|
Circle {
|
||||||
|
pos: board.layout().drawing().primitive(from).shape().center(),
|
||||||
|
r: 20.0,
|
||||||
|
},
|
||||||
|
egui::Color32::from_rgb(255, 255, 100),
|
||||||
|
);
|
||||||
|
painter.paint_dot(
|
||||||
|
Circle {
|
||||||
|
pos: board.layout().drawing().primitive(to).shape().center(),
|
||||||
|
r: 20.0,
|
||||||
|
},
|
||||||
|
egui::Color32::from_rgb(255, 255, 100),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue