summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/src/ui/view/world.rs187
1 files changed, 184 insertions, 3 deletions
diff --git a/engine/src/ui/view/world.rs b/engine/src/ui/view/world.rs
index 335756f..ff4c13a 100644
--- a/engine/src/ui/view/world.rs
+++ b/engine/src/ui/view/world.rs
@@ -1,7 +1,9 @@
use std::any::{Any, TypeId};
use std::borrow::Cow;
use std::io::Cursor;
+use std::ops::{Deref, DerefMut};
+use crate::color::{Rgb, Rgba};
use crate::ecs::actions::Actions;
use crate::ecs::component::local::Local;
use crate::ecs::component::{
@@ -843,6 +845,7 @@ enum ItemType
Reflected(&'static TypeReflection),
String,
CowStr,
+ Color(ColorItemType, LiteralType),
}
impl ItemType
@@ -859,6 +862,7 @@ impl ItemType
Self::Reflected(TypeReflection::Reference(ref_ty)) => {
ItemType::Reflected(ref_ty.ty).spans_multiple_rows()
}
+ Self::Color(..) => false,
Self::Reflected(TypeReflection::Literal(_)) | Self::String | Self::CowStr => {
false
}
@@ -881,11 +885,34 @@ impl ItemType
}
}
+#[derive(Debug)]
+enum ColorItemType
+{
+ Rgb,
+ Rgba,
+}
+
fn get_item_type(ty: Option<&'static TypeReflection>, type_id: TypeId)
-> Option<ItemType>
{
+ if let Some(TypeReflection::Struct(_)) = ty {
+ if type_id == TypeId::of::<Rgb<f32>>() {
+ return Some(ItemType::Color(ColorItemType::Rgb, LiteralType::F32));
+ }
+ if type_id == TypeId::of::<Rgb<u8>>() {
+ return Some(ItemType::Color(ColorItemType::Rgb, LiteralType::U8));
+ }
+
+ if type_id == TypeId::of::<Rgba<f32>>() {
+ return Some(ItemType::Color(ColorItemType::Rgba, LiteralType::F32));
+ }
+ if type_id == TypeId::of::<Rgba<u8>>() {
+ return Some(ItemType::Color(ColorItemType::Rgba, LiteralType::U8));
+ }
+ }
+
if let Some(ty) = ty {
- Some(ItemType::Reflected(ty))
+ return Some(ItemType::Reflected(ty));
} else if type_id == TypeId::of::<String>() {
Some(ItemType::String)
} else if type_id == TypeId::of::<Cow<'static, str>>() {
@@ -901,7 +928,7 @@ enum ItemRef<'item>
Immutable(&'item dyn Any),
}
-impl ItemRef<'_>
+impl<'item> ItemRef<'item>
{
fn get_struct_field(
&mut self,
@@ -934,6 +961,23 @@ impl ItemRef<'_>
}
}
}
+
+ fn into_writable<T: Clone + 'static>(self) -> OwnedOrRefMut<'item, T>
+ {
+ match self {
+ ItemRef::Mutable(item) => OwnedOrRefMut::Ref(
+ (*item)
+ .downcast_mut::<T>()
+ .expect("Cannot downcast: wrong item type"),
+ ),
+ ItemRef::Immutable(item) => OwnedOrRefMut::Owned(
+ (*item)
+ .downcast_ref::<T>()
+ .expect("Cannot downcast: wrong item type")
+ .clone(),
+ ),
+ }
+ }
}
impl AsRef<dyn Any> for ItemRef<'_>
@@ -947,6 +991,37 @@ impl AsRef<dyn Any> for ItemRef<'_>
}
}
+#[derive(Debug)]
+pub enum OwnedOrRefMut<'a, Value>
+{
+ Ref(&'a mut Value),
+ Owned(Value),
+}
+
+impl<Value> Deref for OwnedOrRefMut<'_, Value>
+{
+ type Target = Value;
+
+ fn deref(&self) -> &Self::Target
+ {
+ match self {
+ Self::Ref(value) => *value,
+ Self::Owned(value) => value,
+ }
+ }
+}
+
+impl<Value> DerefMut for OwnedOrRefMut<'_, Value>
+{
+ fn deref_mut(&mut self) -> &mut Self::Target
+ {
+ match self {
+ Self::Ref(value) => *value,
+ Self::Owned(value) => value,
+ }
+ }
+}
+
fn create_item_title_widget(
frame: &dear_imgui_bindings::Ui,
item_title: &str,
@@ -1374,6 +1449,111 @@ fn add_item_to_frame<'a>(
*data_changed = true;
}
}
+ ItemType::Color(ColorItemType::Rgb, LiteralType::F32) => {
+ let mut item = item.into_writable::<Rgb<f32>>();
+
+ let mut scratch = [item.r, item.g, item.b];
+
+ if frame
+ .color_edit3_config(
+ create_item_label(&item_tag, "value_input", &prev_item_tags),
+ &mut scratch,
+ )
+ .display_mode(dear_imgui_bindings::ColorDisplayMode::Hex)
+ .build()
+ {
+ let [new_r, new_g, new_b] = scratch;
+
+ *item = Rgb { r: new_r, g: new_g, b: new_b };
+
+ *data_changed = true;
+ }
+ }
+ ItemType::Color(ColorItemType::Rgb, LiteralType::U8) => {
+ let mut item = item.into_writable::<Rgb<u8>>();
+
+ let mut scratch = [
+ item.r as f32 / 255.0,
+ item.g as f32 / 255.0,
+ item.b as f32 / 255.0,
+ ];
+
+ if frame
+ .color_edit3_config(
+ create_item_label(&item_tag, "value_input", &prev_item_tags),
+ &mut scratch,
+ )
+ .display_mode(dear_imgui_bindings::ColorDisplayMode::Hex)
+ .build()
+ {
+ let [new_r, new_g, new_b] = scratch;
+
+ *item = Rgb {
+ r: (new_r * 255.0) as u8,
+ g: (new_g * 255.0) as u8,
+ b: (new_b * 255.0) as u8,
+ };
+
+ *data_changed = true;
+ }
+ }
+ ItemType::Color(ColorItemType::Rgba, LiteralType::F32) => {
+ let mut item = item.into_writable::<Rgba<f32>>();
+
+ let mut scratch = [item.r, item.g, item.b, item.a];
+
+ if frame
+ .color_edit4_config(
+ create_item_label(&item_tag, "value_input", &prev_item_tags),
+ &mut scratch,
+ )
+ .display_mode(dear_imgui_bindings::ColorDisplayMode::Hex)
+ .build()
+ {
+ let [new_r, new_g, new_b, new_a] = scratch;
+
+ *item = Rgba {
+ r: new_r,
+ g: new_g,
+ b: new_b,
+ a: new_a,
+ };
+
+ *data_changed = true;
+ }
+ }
+ ItemType::Color(ColorItemType::Rgba, LiteralType::U8) => {
+ let mut item = item.into_writable::<Rgba<u8>>();
+
+ let mut scratch = [
+ item.r as f32 / 255.0,
+ item.g as f32 / 255.0,
+ item.b as f32 / 255.0,
+ item.a as f32 / 255.0,
+ ];
+
+ if frame
+ .color_edit4_config(
+ create_item_label(&item_tag, "value_input", &prev_item_tags),
+ &mut scratch,
+ )
+ .display_mode(dear_imgui_bindings::ColorDisplayMode::Hex)
+ .build()
+ {
+ let [new_r, new_g, new_b, new_a] = scratch;
+
+ *item = Rgba {
+ r: (new_r * 255.0) as u8,
+ g: (new_g * 255.0) as u8,
+ b: (new_b * 255.0) as u8,
+ a: (new_a * 255.0) as u8,
+ };
+
+ *data_changed = true;
+ }
+ }
+ ItemType::Color(ColorItemType::Rgb, _) => unreachable!(),
+ ItemType::Color(ColorItemType::Rgba, _) => unreachable!(),
ItemType::Reflected(_) => unimplemented!(),
}
}
@@ -1809,7 +1989,8 @@ fn get_whole_type_is_user_editable(
| TypeReflection::Literal(_),
)
| ItemType::String
- | ItemType::CowStr => true,
+ | ItemType::CowStr
+ | ItemType::Color(..) => true,
ItemType::Reflected(_) => unimplemented!(),
}
}