How is it possible that i cant use this function? - image

using this github repo as a reference: https://github.com/emilk/egui/blob/master/examples/retained_image/src/main.rs
Im trying to load an image into my frame using the egui_extras::RetainedImage, but it is giving me an error that the function RetainedImage::from_image_bytes cannot be found in RetainedImage.
I have also checked image.rs class to make sure that the function is even there, which it is.
here is my code:
use eframe::{run_native, epi::App, egui, NativeOptions};
use egui_extras::RetainedImage;
struct InitView {
image: RetainedImage,
tint: egui::Color32,
}
impl Default for InitView {
fn default() -> Self {
Self {
image: RetainedImage::from_image_bytes(
"date_backdrop.png",
include_bytes!("date_backdrop.png"),
)
.unwrap(),
tint: egui::Color32::from_rgb(255, 0, 255),
}
}
}
impl App for InitView {
fn name(&self) -> &str {
"CheckIt"
}
fn update(&mut self,ctx: &eframe::egui::CtxRef,frame: &mut eframe::epi::Frame<'_>) {
//background color
let frame = egui::containers::Frame {
fill: egui::Color32::from_rgb(241, 233, 218),
..Default::default()
};
//main window
egui::CentralPanel::default().frame(frame).show(ctx, |ui| {
ui.label("test");
});
}
}
fn main(){
let app: InitView = InitView{..Default::default()};
let win_options = eframe::NativeOptions{
initial_window_size: Some(egui::Vec2::new(386.0, 636.0)),
always_on_top: true,
resizable: false,
..Default::default()
};
run_native(Box::new(app), win_options);
}
what im i doing wrong? im still new to rust

You need to add the image feature.
Edit your Cargo.toml and replace egui_extras with egui_extras = { version = "0.20.0", features = ["image"] } or run cargo add egui_extras -F "image" in your project root directory.

Related

egui::TextEdit::singleline with macroquad - not able to edit text

Trying to experiment with egui and macroquad, but can't get elements enabled for edit.
From the standard example:
use macroquad::prelude::*;
#[macroquad::main("")]
async fn main() {
loop {
clear_background(BLACK);
egui_macroquad::ui(|egui_ctx| {
egui_macroquad::egui::Window::new("egui ❤ macroquad").show(egui_ctx, |ui| {
ui.colored_label(egui_macroquad::egui::Color32::WHITE, "Test");
ui.add(egui_macroquad::egui::TextEdit::singleline(&mut "ku").text_color(egui_macroquad::egui::Color32::RED));
});
});
egui_macroquad::draw();
next_frame().await
}
}
In Cargo.toml:
[dependencies]
macroquad = "0.3.25"
egui-macroquad = "0.12.0"
As result:
I see the TextEdit::singleline widget, but can't edit it.
Should I enable it somehow or something else?
Found the solution. Mutable "String" variable must be defined and used for TextEdit::singleline:
use macroquad::prelude::*;
#[macroquad::main("")]
async fn main() {
let mut kuku: String = "ku".to_string();
loop {
clear_background(BLACK);
egui_macroquad::ui(|egui_ctx| {
egui_macroquad::egui::Window::new("egui ❤ macroquad").show(egui_ctx, |ui| {
ui.colored_label(egui_macroquad::egui::Color32::WHITE, "Test");
ui.add(egui_macroquad::egui::TextEdit::singleline(&mut kuku).text_color(egui_macroquad::egui::Color32::RED));
});
});
egui_macroquad::draw();
next_frame().await
}
}
Now it works, because it takes the values from the widget and assign them to the variable "kuku".

Why cant i allocate a texture to the GPU memmory?

i am trying to import a backdrop for my application and using a image as that backdrop, but cant seem to get it to work. Im using this example on loading images in; https://github.com/emilk/egui/blob/c69fe941afdea5ef6f3f84ed063554500b6262e8/eframe/examples/image.rs
Here is my code:
use eframe::{run_native, epi::App, egui, NativeOptions};
use image::GenericImageView;
struct Tasks{
texture: Option<(egui::Vec2, egui::TextureId)>,
}
impl App for Tasks {
fn name(&self) -> &str {
"CheckIt"
}
fn update(&mut self,ctx: &eframe::egui::CtxRef,frame: &mut eframe::epi::Frame<'_>) {
//background color
let frame = egui::containers::Frame {
fill: egui::Color32::from_rgb(241, 233, 218),
..Default::default()
};
if self.texture.is_none() {
// Load the image:
let image_data = include_bytes!("date_backdrop.png");
let image = image::load_from_memory(image_data).expect("Failed to load image");
let image_buffer = image.to_rgba8();
let size = (image.width() as usize, image.height() as usize);
let pixels = image_buffer.into_vec();
assert_eq!(size.0 * size.1 * 4, pixels.len());
let pixels: Vec<_> = pixels
.chunks_exact(4)
.map(|p| egui::Color32::from_rgba_unmultiplied(p[0], p[1], p[2], p[3]))
.collect();
// Allocate a texture:
let texture = ctx.tex_allocator().alloc_srgba_premultiplied(size, &pixels);
let size = egui::Vec2::new(size.0 as f32, size.1 as f32);
self.texture = Some((size, texture));
}
//main window
egui::CentralPanel::default().frame(frame).show(ctx, |ui| {
if let Some((size, texture)) = self.texture {
ui.heading("This is an image:");
ui.image(texture, size);
ui.heading("This is an image you can click:");
ui.add(egui::ImageButton::new(texture, size));
}
});
}
}
fn main(){
let app: Tasks = Tasks{texture: None};
let win_options = eframe::NativeOptions{
initial_window_size: Some(egui::Vec2::new(386.0, 636.0)),
always_on_top: true,
resizable: false,
..Default::default()
};
run_native(Box::new(app), win_options);
}
im getting an error on this line of code
let texture = ctx.tex_allocator().alloc_srgba_premultiplied(size, &pixels);
here is the error message: no method named tex_allocator found for reference &CtxRef in the current scope
method not found in &CtxRef
im still new to rust and building ui with it.
I have tried asking ChatGPT and googleing the problem but to no success

How to Filter out a Vec of Strings From a Vec of Structs Rust

I have a working solution to filtering out an input vec of strings compared to a vector of a struct. However, my code seems complicated and I tried simplify the code using a iter::filter(https://doc.rust-lang.org/stable/std/iter/struct.Filter.html). This caused issues because the iterator gave back values that were references and could not be directly used. It seems like my understanding of the iter and what can be done in a structs vector needs refreshing. Below is the simplified filtering code that works:
#[derive(Debug)]
pub struct Widget {
name: String,
pin: u16,
}
impl Widget{
pub fn new(widget_name: String, widget_pin: String) -> Widget {
let widget_pin_u16 = widget_pin.parse::<u16>().expect("Unable to parse");
let nw = Widget {
name: widget_name,
pin: widget_pin_u16
};
return nw
}
}
pub struct WidgetHolder {
widgets: Vec<Widget>,
widget_holder_name: String
}
impl WidgetHolder {
fn add_widgets(&mut self, valid_widgets_found: Vec<String>) {
let mut widgets_to_add: Vec<String> = Vec::new();
for widget in valid_widgets_found {
// The string musy be compared to pin field, so we're converting
let widget_offset = widget
.clone()
.parse::<u16>()
.expect("Unable to parse widget base into int.");
// If it doesnt exist in our widgetHolder widgets vector, then lets add it.
let mut widget_exists = false;
for existing_widget in &self.widgets {
if widget_offset == existing_widget.pin {
widget_exists = true;
break;
}
}
if !widget_exists {
widgets_to_add.push(widget.clone());
}
}
if widgets_to_add.is_empty() {
return;
}
for widget in widgets_to_add {
let loaded_widget = Widget::new(self.widget_holder_name.clone(), widget);
self.widgets.push(loaded_widget);
}
}
}
pub fn main() {
let init_vec = Vec::new();
let mut wh = WidgetHolder {
widgets: init_vec,
widget_holder_name: "MyWidget".to_string()
};
let vec1 = vec!["1".to_string(), "2".to_string(), "3".to_string()];
wh.add_widgets(vec1);
println!("{:?}", wh.widgets);
let vec2 = vec!["2".to_string(), "3".to_string(), "4".to_string()];
wh.add_widgets(vec2);
println!("{:?}", wh.widgets);
}
Is there a way I can clean up this code without having to use so many data structures and loops? The filter api looks clean but does it work with a vector inside of a struct that I am trying to mutate(append to it)?
EDIT
After trying to get a stack trace, I actually got the filter to work...
fn add_widgets(&mut self, valid_widgets_found: Vec<String>) {
let widgets_to_add: Vec<String> = valid_widgets_found.into_iter()
.filter(|widget_pin| {
let widget_offset = widget_pin.clone().parse::<u16>().expect("Unable to parse widget base into int.");
let mut widget_exists = false;
for existing_widget in &self.widgets {
if widget_offset == existing_widget.pin {
widget_exists = true;
break;
}
}
!widget_exists
})
.collect();
if widgets_to_add.is_empty() {
return;
}
for widget in widgets_to_add {
let loaded_widget = Widget::new(self.widget_holder_name.clone(), widget);
self.widgets.push(loaded_widget);
}
}
I figured out the answer. Seemed like a syntax error when I initially tried it. For anyone who's looking for a filter example in the future:
fn add_widgets(&mut self, valid_widgets_found: Vec<String>) {
let widgets_to_add: Vec<String> = valid_widgets_found.into_iter()
.filter(|widget_pin| {
let widget_offset = widget_pin.clone().parse::<u16>().expect("Unable to parse widget base into int.");
let mut widget_exists = false;
for existing_widget in &self.widgets {
if widget_offset == existing_widget.pin {
widget_exists = true;
break;
}
}
!widget_exists
})
.collect();
if widgets_to_add.is_empty() {
return;
}
for widget in widgets_to_add {
let loaded_widget = Widget::new(self.widget_holder_name.clone(), widget);
self.widgets.push(loaded_widget);
}
}

egui combobox vector for selected

I am trying to use a vector instead of the enum specified in the docs but I have no clue how to implement the selected part. My current code is
egui::ComboBox::from_label("Take your pick")
.selected_text(format!("{}", self.radio[0]))
.show_ui(ui, |ui| {
for i in 0..self.radio.len() {
ui.selectable_value(&mut &self.radio, &self.radio, &self.radio[i]);
}
});
can anyone give me an idea. I do not mind using enum but I do not know how many things will be in it.
I stumbled on the same problem, and I have found a solution. The solution is to add a new Variable to the self. Here is a basic example on the Enum select and the Vector select. Hope this helps out anyone who has run into the same problem.
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use eframe::egui;
fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(
"Test Select with Enum and Vector",
options,
Box::new(|_cc| Box::new(MyApp::default())),
);
}
#[derive(PartialEq)]
#[derive(Debug)]
enum OS_Select {
First,
Second,
Third,
}
struct MyApp {
selected: usize,
radio: OS_Select,
selector_vec: Vec<String>,
}
impl Default for MyApp {
fn default() -> Self {
Self {
selected: 0,
radio: OS_Select::First,
selector_vec: get_vec(),
}
}
}
fn get_vec() -> Vec<String> {
let vecs = [
"1".to_string(),
"2".to_string(),
"3".to_string(),
].to_vec();
return vecs;
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Select with enum");
ui.horizontal(|ui| {
ui.radio_value(&mut self.radio, OS_Select::First, "First");
ui.radio_value(&mut self.radio, OS_Select::Second, "Second");
ui.radio_value(&mut self.radio, OS_Select::Third, "Third");
});
ui.end_row();
ui.heading("Select with Vectors");
egui::ComboBox::from_label("Take your pick")
.selected_text(format!("{}", &self.selector_vec[self.selected]))
.show_ui(ui, |ui| {
for i in 0..self.selector_vec.len() {
let value = ui.selectable_value(&mut &self.selector_vec[i], &self.selector_vec[self.selected], &self.selector_vec[i]);
if (value.clicked()) {
self.selected = i;
}
}
});
ui.end_row();
});
}
fn save(&mut self, _storage: &mut dyn eframe::Storage) {}
fn on_close_event(&mut self) -> bool {
true
}
fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) {}
fn auto_save_interval(&self) -> std::time::Duration {
std::time::Duration::from_secs(30)
}
fn max_size_points(&self) -> egui::Vec2 {
egui::Vec2::INFINITY
}
fn clear_color(&self, _visuals: &egui::Visuals) -> egui::Rgba {
// NOTE: a bright gray makes the shadows of the windows look weird.
// We use a bit of transparency so that if the user switches on the
// `transparent()` option they get immediate results.
egui::Color32::from_rgba_unmultiplied(12, 12, 12, 180).into()
// _visuals.window_fill() would also be a natural choice
}
fn persist_native_window(&self) -> bool {
true
}
fn persist_egui_memory(&self) -> bool {
true
}
fn warm_up_enabled(&self) -> bool {
false
}
fn post_rendering(&mut self, _window_size_px: [u32; 2], _frame: &eframe::Frame) {}
}

Is there a way to directly access a field value in an enum struct without pattern matching?

I wish that enums in Rust can be used like Haskell's productive type. I want to
access a field's value directly
assign a field's value directly or make a clone with the changing value.
Directly means that not using too long pattern matching code, but just could access like let a_size = a.size.
In Haskell:
data TypeAB = A {size::Int, name::String} | B {size::Int, switch::Bool} deriving Show
main = do
let a = A 1 "abc"
let b = B 1 True
print (size a) -- could access a field's value directly
print (name a) -- could access a field's value directly
print (switch b) -- could access a field's value directly
let aa = a{size=2} -- could make a clone directly with the changing value
print aa
I tried two styles of Rust enum definition like
Style A:
#[derive(Debug)]
enum EntryType {
A(TypeA),
B(TypeB),
}
#[derive(Debug)]
struct TypeA {
size: u32,
name: String,
}
#[derive(Debug)]
struct TypeB {
size: u32,
switch: bool,
}
fn main() {
let mut ta = TypeA {
size: 3,
name: "TAB".to_string(),
};
println!("{:?}", &ta);
ta.size = 2;
ta.name = "TCD".to_string();
println!("{:?}", &ta);
let mut ea = EntryType::A(TypeA {
size: 1,
name: "abc".to_string(),
});
let mut eb = EntryType::B(TypeB {
size: 1,
switch: true,
});
let vec_ab = vec![&ea, &eb];
println!("{:?}", &ea);
println!("{:?}", &eb);
println!("{:?}", &vec_ab);
// Want to do like `ta.size = 2` for ea
// Want to do like `ta.name = "bcd".to_string()` for ea
// Want to do like `tb.switch = false` for eb
// ????
println!("{:?}", &ea);
println!("{:?}", &eb);
println!("{:?}", &vec_ab);
}
Style B:
#[derive(Debug)]
enum TypeCD {
TypeC { size: u32, name: String },
TypeD { size: u32, switch: bool },
}
fn main() {
// NOTE: Rust requires representative struct name before each constructor
// TODO: Check constructor name can be duplicated
let mut c = TypeCD::TypeC {
size: 1,
name: "abc".to_string(),
};
let mut d = TypeCD::TypeD {
size: 1,
switch: true,
};
let vec_cd = vec![&c, &d];
println!("{:?}", &c);
println!("{:?}", &d);
println!("{:?}", &vec_cd);
// Can't access a field's value like
// let c_size = c.size
let c_size = c.size; // [ERROR]: No field `size` on `TypeCD`
let c_name = c.name; // [ERROR]: No field `name` on `TypeCD`
let d_switch = d.switch; // [ERROR]: No field `switch` on `TypeCD`
// Can't change a field's value like
// c.size = 2;
// c.name = "cde".to_string();
// d.switch = false;
println!("{:?}", &c);
println!("{:?}", &d);
println!("{:?}", &vec_cd);
}
I couldn't access/assign values directly in any style. Do I have to implement functions or a trait just to access a field's value? Is there some way of deriving things to help this situation?
What about style C:
#[derive(Debug)]
enum Color {
Green { name: String },
Blue { switch: bool },
}
#[derive(Debug)]
struct Something {
size: u32,
color: Color,
}
fn main() {
let c = Something {
size: 1,
color: Color::Green {
name: "green".to_string(),
},
};
let d = Something {
size: 2,
color: Color::Blue { switch: true },
};
let vec_cd = vec![&c, &d];
println!("{:?}", &c);
println!("{:?}", &d);
println!("{:?}", &vec_cd);
let _ = c.size;
}
If all variant have something in common, why separate them?
Of course, I need to access not common field too.
This would imply that Rust should define what to do when the actual type at runtime doesn't contain the field you required. So, I don't think Rust would add this one day.
You could do it yourself. It will require some lines of code, but that matches the behavior of your Haskell code. However, I don't think this is the best thing to do. Haskell is Haskell, I think you should code in Rust and not try to code Haskell by using Rust. That a general rule, some feature of Rust come directly from Haskell, but what you want here is very odd in my opinion for Rust code.
#[derive(Debug)]
enum Something {
A { size: u32, name: String },
B { size: u32, switch: bool },
}
impl Something {
fn size(&self) -> u32 {
match self {
Something::A { size, .. } => *size,
Something::B { size, .. } => *size,
}
}
fn name(&self) -> &String {
match self {
Something::A { name, .. } => name,
Something::B { .. } => panic!("Something::B doesn't have name field"),
}
}
fn switch(&self) -> bool {
match self {
Something::A { .. } => panic!("Something::A doesn't have switch field"),
Something::B { switch, .. } => *switch,
}
}
fn new_size(&self, size: u32) -> Something {
match self {
Something::A { name, .. } => Something::A {
size,
name: name.clone(),
},
Something::B { switch, .. } => Something::B {
size,
switch: *switch,
},
}
}
// etc...
}
fn main() {
let a = Something::A {
size: 1,
name: "Rust is not haskell".to_string(),
};
println!("{:?}", a.size());
println!("{:?}", a.name());
let b = Something::B {
size: 1,
switch: true,
};
println!("{:?}", b.switch());
let aa = a.new_size(2);
println!("{:?}", aa);
}
I think there is currently no built-in way of accessing size directly on the enum type. Until then, enum_dispatch or a macro-based solution may help you.

Resources