#![allow(unused_imports)]
#![allow(unused_variables)]
use crate::model::TingeState::*;
use crate::model::*;
use log::info;
use num_traits::FromPrimitive;
use tinge_lib::COLORS_WITH_NAME;
use rust_pixel::{
asset::AssetType,
asset2sprite,
context::Context,
event::{event_check, event_register},
game::{Model, Render},
render::panel::Panel,
render::sprite::Sprite,
render::style::{Color, ColorData, ColorPro, ColorSpace::*, Style},
util::Rect,
};
use std::cell::Cell;
pub struct TingeRender {
pub panel: Panel,
}
impl TingeRender {
pub fn new() -> Self {
let mut panel = Panel::new();
panel.add_layer("main");
let gb = Sprite::new(0, 0, PALETTEW, PALETTEH);
panel.add_layer_sprite(gb, "main", "back");
let mb = Sprite::new(MENUX, MENUY, MENUW, 1);
panel.add_layer_sprite(mb, "main", "menu");
let pl = Sprite::new(4, 24, 12, 6);
panel.add_layer_sprite(pl, "main", "main_color");
for i in 0..3 {
let pl = Sprite::new(61, 25 + i * 2, C_WIDTH - 2, 1);
panel.add_layer_sprite(pl, "main", &format!("simi{}", i));
}
let pl = Sprite::new(2, 22, 40, 1);
panel.add_layer_sprite(pl, "main", "main_color_str");
for i in 0..MAIN_COLOR_MSG_Y {
for j in 0..MAIN_COLOR_MSG_X {
let pl = Sprite::new(j * 20 + 22, 23 + i, 40, 1);
panel.add_layer_sprite(
pl,
"main",
&format!("main_color_str{}", i * MAIN_COLOR_MSG_X + j),
);
}
}
let help_msg = [
"← ↑ → ↓ mouse : select named colors n : colors list 2",
"← ↑ → ↓ mouse : select named colors n : colors list 1",
"tab : switch select area ← ↑ → ↓ mouse : change value n : rgb picker",
"tab : switch select area ← ↑ → ↓ mouse : change value n : hsv picker",
"← ↑ → ↓ mouse : select random colors",
"a : add input color d : delete input color tab ← ↑ → ↓ : change value",
"← ↑ → ↓ mouse : select PHI(golden ratio) colors",
];
for i in 0..7 {
let ls = format!("{}", i);
panel.add_layer(&ls);
let mut pl = Sprite::new(ADJX + 1, ADJY + 30, C_WIDTH * 4, 1);
pl.set_color_str(0, 0, help_msg[i], Color::Gray, Color::Reset);
panel.add_layer_sprite(pl, &ls, "help_msg");
if i != 0 {
panel.deactive_layer(&ls);
}
}
for i in 0..2 {
for row in 0..ROW_COUNT {
for col in 0..COL_COUNT {
let pl = Sprite::new(ADJX + col * C_WIDTH + 1, ADJY + row, C_WIDTH - 1, 1);
let idx = (ROW_COUNT * COL_COUNT * i + row * COL_COUNT + col) as usize;
if idx >= COLORS_WITH_NAME.len() {
break;
}
panel.add_layer_sprite(pl, &format!("{}", i), &format!("{}", idx));
}
}
}
for y in 0..PICKER_COUNT_Y {
for x in 0..PICKER_COUNT_X {
let pl = Sprite::new(ADJX + x, ADJY + y, 1, 1);
panel.add_layer_sprite(pl, "2", &format!("pick{}", y * PICKER_COUNT_X + x));
}
}
for i in 0..PICKER_COUNT_X {
let pl = Sprite::new(2 + i, 20, 1, 1);
panel.add_layer_sprite(pl, "2", &format!("hsv_pick{}", i));
}
let pcs = [Color::Red, Color::Green, Color::Blue];
for y in 0..3 {
for x in 0..PICKER_COUNT_X {
let mut pl = Sprite::new(2 + x, 9 + y * 2, 1, 1);
pl.set_color_str(0, 0, " ", Color::Reset, pcs[y as usize]);
panel.add_layer_sprite(pl, "3", &format!("rgb_pick_{}_{}", y, x));
}
}
for y in 0..RANDOM_Y {
for x in 0..RANDOM_X {
let pl = Sprite::new(ADJX + x * RANDOM_W, ADJY + y, RANDOM_W - 1, 1);
panel.add_layer_sprite(pl, "4", &format!("random{}", y * RANDOM_X + x));
}
}
for y in 0..RANDOM_Y {
for x in 0..RANDOM_X {
let pl = Sprite::new(ADJX + x * RANDOM_W, ADJY + y, RANDOM_W - 1, 1);
panel.add_layer_sprite(pl, "6", &format!("random{}", y * RANDOM_X + x));
}
}
for y in 0..PICKER_COUNT_Y {
for x in 0..PICKER_COUNT_X_GRADIENT {
let pl = Sprite::new(ADJX + x, ADJY + y, 1, 1);
panel.add_layer_sprite(pl, "5", &format!("pick{}", y * PICKER_COUNT_X + x));
}
}
for i in 0..PICKER_COUNT_X_GRADIENT {
let pl = Sprite::new(2 + i, 20, 1, 1);
panel.add_layer_sprite(pl, "5", &format!("hsv_pick{}", i));
}
for i in 0..GRADIENT_INPUT_COUNT {
let pl = Sprite::new(60, i as u16 + ADJY, 8, 1);
panel.add_layer_sprite(pl, "5", &format!("gi_input{}", i));
}
for y in 0..GRADIENT_Y {
for x in 0..GRADIENT_X {
let pl = Sprite::new(67 + ADJX, y as u16 + ADJY, 9, 1);
panel.add_layer_sprite(pl, "5", &format!("gi{}", y * GRADIENT_X + x));
}
}
panel.add_layer("select");
for i in 0..5 {
let pl = Sprite::new(0, 0, 1, 1);
panel.add_layer_sprite(pl, "select", &format!("cursor{}", i));
}
event_register("Tinge.RedrawSelect", "draw_select");
event_register("Tinge.RedrawMenu", "draw_menu");
event_register("Tinge.RedrawPanel", "draw_panel");
event_register("Tinge.RedrawMainColor", "draw_main_color");
event_register("Tinge.RedrawPicker", "draw_picker");
event_register("Tinge.RedrawGradient", "draw_gradient");
event_register("Tinge.RedrawRandom", "draw_random");
Self { panel }
}
pub fn draw_select<G: Model>(&mut self, ctx: &mut Context, model: &mut G) {
let d = model.as_any().downcast_mut::<TingeModel>().unwrap();
let state = TingeState::from_usize(ctx.state as usize).unwrap();
match state {
NameA | NameB => {
let pl = self.panel.get_layer_sprite("select", "cursor0");
let idx = d.select.cur().y * COL_COUNT as usize
+ d.select.cur().x
+ ctx.state as usize * 76;
let cr = d.named_colors[idx].1;
pl.set_color_str(0, 0, "", Color::Green, Color::Black);
pl.set_pos(
2 + d.select.cur().x as u16 * C_WIDTH,
2 + d.select.cur().y as u16,
);
for i in 1..5 {
let pl = self
.panel
.get_layer_sprite("select", &format!("cursor{}", i));
pl.set_hidden(true);
}
}
Random | Golden => {
let pl = self.panel.get_layer_sprite("select", "cursor0");
let idx = d.select.cur().y * RANDOM_X as usize + d.select.cur().x;
let cr = d.random_colors[idx];
pl.set_color_str(0, 0, "", Color::Green, Color::Black);
pl.set_pos(
1 + d.select.cur().x as u16 * RANDOM_W,
2 + d.select.cur().y as u16,
);
for i in 1..5 {
let pl = self
.panel
.get_layer_sprite("select", &format!("cursor{}", i));
pl.set_hidden(true);
}
}
PickerB => {
let pl = self.panel.get_layer_sprite("select", "cursor0");
let idx = d.select.area;
pl.set_color_str(0, 0, "", Color::Green, Color::Black);
pl.set_pos(1, 9 + idx as u16 * 2);
let bcs = [Color::Red, Color::Green, Color::Blue];
for i in 0..3 {
let pl = self.panel.get_layer_sprite("select", &format!("cursor{}", i+1));
pl.set_color_str(0, 0, "∙", Color::Black, bcs[i]);
let x = d.select.ranges[i].x;
pl.set_pos((x as f64 / 256.0 * PICKER_COUNT_X as f64) as u16 + 2, 9 + i as u16 * 2);
pl.set_hidden(false);
}
}
PickerA | Gradient => {
let pl = self.panel.get_layer_sprite("select", "cursor0");
let idx = d.select.area;
pl.set_color_str(0, 0, "", Color::Green, Color::Black);
if state == PickerA {
pl.set_pos(1, idx as u16 * 18 + 2);
} else {
if idx < 3 {
pl.set_pos(
1 + idx as u16 / 2 * (PICKER_COUNT_X_GRADIENT + 1),
idx as u16 % 2 * 18 + 2,
);
} else {
pl.set_pos(PICKER_COUNT_X_GRADIENT + 11, (idx - 1) as u16 % 2 * 18 + 2);
}
}
if state == Gradient {
let pl = self.panel.get_layer_sprite("select", "cursor3");
if d.gradient_input_colors.len() != 0 {
let cr = d.gradient_input_colors[d.select.ranges[2].y];
pl.set_color_str(
0,
0,
"∙",
if cr.is_dark() {
Color::White
} else {
Color::Black
},
Color::Professional(cr),
);
pl.set_pos(
d.select.ranges[2].x as u16 + 3 + PICKER_COUNT_X_GRADIENT,
d.select.ranges[2].y as u16 + 2,
);
pl.set_hidden(false);
} else {
pl.set_hidden(true);
}
let pl = self.panel.get_layer_sprite("select", "cursor4");
if d.gradient_colors.len() != 0 {
let cr = d.gradient_colors[d.select.ranges[3].y];
pl.set_color_str(
0,
0,
"∙",
if cr.is_dark() {
Color::White
} else {
Color::Black
},
Color::Professional(cr),
);
pl.set_pos(
d.select.ranges[3].x as u16 + 12 + PICKER_COUNT_X_GRADIENT,
d.select.ranges[3].y as u16 + 2,
);
pl.set_hidden(false);
} else {
pl.set_hidden(true);
}
} else {
for i in 3..5 {
let pl = self
.panel
.get_layer_sprite("select", &format!("cursor{}", i));
pl.set_hidden(true);
}
}
let pl = self.panel.get_layer_sprite("select", "cursor1");
let cr = get_pick_color(
if ctx.state == 2 {
PICKER_COUNT_X as usize
} else {
PICKER_COUNT_X_GRADIENT as usize
},
d.select.ranges[0].x,
d.select.ranges[0].y,
d.select.ranges[1].x,
0,
);
pl.set_color_str(
0,
0,
"∙",
if cr.is_dark() {
Color::White
} else {
Color::Black
},
Color::Professional(cr),
);
pl.set_pos(
d.select.ranges[0].x as u16 + 2,
d.select.ranges[0].y as u16 + 2,
);
pl.set_hidden(false);
let pl = self.panel.get_layer_sprite("select", "cursor2");
let cr = get_pick_color(
if ctx.state == 2 {
PICKER_COUNT_X as usize
} else {
PICKER_COUNT_X_GRADIENT as usize
},
d.select.ranges[0].x,
d.select.ranges[0].y,
d.select.ranges[1].x,
1,
);
pl.set_color_str(
0,
0,
"∙",
if cr.is_dark() {
Color::White
} else {
Color::Black
},
Color::Professional(cr),
);
pl.set_pos((d.select.ranges[1].x / 4) as u16 + 2, 20);
pl.set_hidden(false);
}
}
}
pub fn draw_panel<G: Model>(&mut self, ctx: &mut Context, model: &mut G) {
let d = model.as_any().downcast_mut::<TingeModel>().unwrap();
info!("draw_panel_clear....");
for i in 0..7 {
if i != ctx.state as usize {
self.panel.deactive_layer(&format!("{}", i));
} else {
self.panel.active_layer(&format!("{}", i));
}
}
}
pub fn draw_gradient<G: Model>(&mut self, ctx: &mut Context, model: &mut G) {
let d = model.as_any().downcast_mut::<TingeModel>().unwrap();
if ctx.state != Gradient as u8 {
return;
}
for i in 0..GRADIENT_INPUT_COUNT {
let pl = self.panel.get_layer_sprite("5", &format!("gi_input{}", i));
if i < d.gradient_input_colors.len() as u16 {
pl.set_hidden(false);
pl.set_color_str(
0,
0,
"████████",
Color::Professional(d.gradient_input_colors[i as usize]),
Color::Reset,
);
} else {
pl.set_hidden(true);
}
}
for y in 0..GRADIENT_Y {
for x in 0..GRADIENT_X {
let idx = y * GRADIENT_X + x;
let pl = self.panel.get_layer_sprite("5", &format!("gi{}", idx));
if idx < d.gradient_colors.len() as u16 {
pl.set_hidden(false);
pl.set_color_str(
0,
0,
" ",
Color::White,
Color::Professional(d.gradient_colors[idx as usize]),
);
} else {
pl.set_hidden(true);
}
}
}
}
pub fn draw_random<G: Model>(&mut self, ctx: &mut Context, model: &mut G) {
let d = model.as_any().downcast_mut::<TingeModel>().unwrap();
if ctx.state != 4 && ctx.state != 6 {
return;
}
let ls = format!("{}", ctx.state);
for y in 0..RANDOM_Y {
for x in 0..RANDOM_X {
let i = y * RANDOM_X + x;
let pl = self.panel.get_layer_sprite(&ls, &format!("random{}", i));
pl.set_color_str(
0,
0,
&format!(" {:width$}", " ", width = C_WIDTH as usize - 1),
Color::Reset,
Color::Professional(d.random_colors[i as usize]),
);
}
}
}
pub fn draw_picker<G: Model>(&mut self, ctx: &mut Context, model: &mut G) {
let d = model.as_any().downcast_mut::<TingeModel>().unwrap();
let state = TingeState::from_usize(ctx.state as usize).unwrap();
match state {
PickerA | Gradient => {
let w = if ctx.state == 2 {
PICKER_COUNT_X
} else {
PICKER_COUNT_X_GRADIENT
};
for y in 0..PICKER_COUNT_Y {
for x in 0..w {
let pl = self.panel.get_layer_sprite(
&format!("{}", ctx.state),
&format!("pick{}", y * PICKER_COUNT_X + x),
);
let cr = get_pick_color(
w as usize,
x as usize,
y as usize,
d.select.ranges[1].x,
0,
);
let color = Color::Professional(cr);
pl.set_color_str(0, 0, " ", color, color);
pl.set_color_str(0, 0, " ", color, color);
}
}
for i in 0..w {
let pl = self
.panel
.get_layer_sprite(&format!("{}", ctx.state), &format!("hsv_pick{}", i));
let cr = ColorPro::from_space_f64(
HSVA,
i as f64 * (360.0 / w as f64),
1.0,
1.0,
1.0,
);
let color = Color::Professional(cr);
pl.set_color_str(0, 0, " ", color, color);
}
}
PickerB => {}
_ => {}
}
}
pub fn draw_named_colors<G: Model>(&mut self, ctx: &mut Context, model: &mut G) {
let d = model.as_any().downcast_mut::<TingeModel>().unwrap();
for i in 0..2 {
for row in 0..ROW_COUNT {
for col in 0..COL_COUNT {
let idx = (ROW_COUNT * COL_COUNT * i + row * COL_COUNT + col) as usize;
if idx >= COLORS_WITH_NAME.len() {
break;
}
let pl = self
.panel
.get_layer_sprite(&format!("{}", i), &format!("{}", idx));
let s = d.named_colors[idx].0;
let cr = d.named_colors[idx].1;
let color = Color::Professional(cr);
pl.set_color_str(
0,
0,
&format!("{:width$}", s, width = C_WIDTH as usize - 1),
if cr.is_dark() {
Color::White
} else {
Color::Black
},
color,
);
}
}
}
}
pub fn draw_main_color<G: Model>(&mut self, ctx: &mut Context, model: &mut G) {
let d = model.as_any().downcast_mut::<TingeModel>().unwrap();
let pl = self.panel.get_layer_sprite("main", "main_color");
for i in 0..6 {
pl.set_color_str(
0,
i,
" ",
Color::White,
Color::Professional(d.main_color),
);
}
let pl = self.panel.get_layer_sprite("main", "main_color_str");
let rgb = d.main_color.get_srgba_u8();
pl.set_color_str(
0,
0,
&format!("{:width$}", &get_color_info(d.main_color, 0), width = 18),
Color::DarkGray,
Color::Black,
);
for i in 0..MAIN_COLOR_MSG_Y {
for j in 0..MAIN_COLOR_MSG_X {
let pl = self.panel.get_layer_sprite(
"main",
&format!("main_color_str{}", i * MAIN_COLOR_MSG_X + j),
);
pl.set_color_str(
0,
0,
&format!(
"{:width$}",
&get_color_info(d.main_color, i * MAIN_COLOR_MSG_X + j + 1),
width = 18
),
if i % 2 == 0 {
Color::Rgba(125, 130, 130, 255)
} else {
Color::Rgba(132, 132, 127, 255)
},
Color::Black,
);
}
}
let mut ids: Vec<usize> = vec![];
ids.push(d.main_color_similar.0);
ids.push(d.main_color_similar.1);
ids.push(d.main_color_similar.2);
for i in 0..3 {
let pl = self.panel.get_layer_sprite("main", &format!("simi{}", i));
let s = COLORS_WITH_NAME[ids[i]].0;
let cr = COLORS_WITH_NAME[ids[i]].1;
let color = Color::Professional(cr);
pl.set_color_str(
0,
0,
&format!("{:width$}", s, width = C_WIDTH as usize),
if cr.is_dark() {
Color::White
} else {
Color::Black
},
color,
);
}
}
pub fn draw_menu<G: Model>(&mut self, ctx: &mut Context, model: &mut G) {
let d = model.as_any().downcast_mut::<TingeModel>().unwrap();
let state = TingeState::from_usize(ctx.state as usize).unwrap();
let mb = self.panel.get_layer_sprite("main", "menu");
let cst = match state {
NameA | NameB => 0,
PickerA | PickerB => 1,
Random => 2,
Gradient => 3,
Golden => 4,
};
let mut xoff = 0u16;
let mcolor = [237, 120, 245, 0, 7, 120];
if cst == 0 {
mb.set_color_str(
xoff,
0,
"",
Color::Indexed(mcolor[0]),
Color::Indexed(mcolor[1]),
);
} else {
mb.set_color_str(
xoff,
0,
"",
Color::Indexed(mcolor[2]),
Color::Indexed(mcolor[0]),
);
}
let menu_title = [
" 1 Named ",
" 2 Picker ",
" 3 Random ",
" 4 Gradient ",
" 5 Golden ",
];
for i in 0..5 {
let fg = if cst == i {
Color::Indexed(mcolor[3])
} else {
Color::Indexed(mcolor[4])
};
let bg = if cst == i {
Color::Indexed(mcolor[1])
} else {
Color::Indexed(mcolor[0])
};
let menu_str = &menu_title[i as usize];
if cst == i {
mb.set_color_str(xoff, 0, "", Color::Indexed(mcolor[0]), bg);
}
xoff += 1;
mb.set_color_str(xoff, 0, menu_str, fg, bg);
xoff += menu_str.len() as u16;
if cst == i {
mb.set_color_str(xoff, 0, "", bg, Color::Indexed(mcolor[0]));
} else {
mb.set_color_str(xoff, 0, "", Color::Indexed(mcolor[2]), bg);
}
}
}
}
impl Render for TingeRender {
fn init<G: Model>(&mut self, context: &mut Context, data: &mut G) {
context
.adapter
.init(PALETTEW + 2, PALETTEH, 1.0, 1.0, "palette".to_string());
self.panel.init(context);
self.draw_menu(context, data);
let d = data.as_any().downcast_mut::<TingeModel>().unwrap();
let gb = self.panel.get_layer_sprite("main", "back");
asset2sprite!(gb, context, "back.txt");
self.draw_named_colors(context, data);
}
fn handle_event<G: Model>(&mut self, context: &mut Context, data: &mut G, _dt: f32) {
if event_check("Tinge.RedrawSelect", "draw_select") {
self.draw_select(context, data);
}
if event_check("Tinge.RedrawMenu", "draw_menu") {
self.draw_menu(context, data);
}
if event_check("Tinge.RedrawPanel", "draw_panel") {
self.draw_panel(context, data);
}
if event_check("Tinge.RedrawMainColor", "draw_main_color") {
self.draw_main_color(context, data);
}
if event_check("Tinge.RedrawPicker", "draw_picker") {
self.draw_picker(context, data);
}
if event_check("Tinge.RedrawGradient", "draw_gradient") {
self.draw_gradient(context, data);
}
if event_check("Tinge.RedrawRandom", "draw_random") {
self.draw_random(context, data);
}
}
fn handle_timer<G: Model>(&mut self, _context: &mut Context, _model: &mut G, _dt: f32) {}
fn draw<G: Model>(&mut self, ctx: &mut Context, data: &mut G, dt: f32) {
self.panel.draw(ctx).unwrap();
}
}