Add from_data
This commit is contained in:
parent
113ac26d38
commit
09b86d9aab
@ -1,23 +1,36 @@
|
|||||||
use eframe::{Frame, NativeOptions};
|
use eframe::{Frame, NativeOptions};
|
||||||
use egui::{CentralPanel, Context, Widget};
|
use egui::{CentralPanel, Context, TextEdit, TopBottomPanel, Widget};
|
||||||
use egui_qr::QrCodeWidget;
|
use egui_qr::QrCodeWidget;
|
||||||
use qrcode::QrCode;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = eframe::run_native(
|
let _ = eframe::run_native(
|
||||||
"egui_qr",
|
"egui_qr",
|
||||||
NativeOptions::default(),
|
NativeOptions::default(),
|
||||||
Box::new(|_| Box::new(App)),
|
Box::new(|_| Box::new(App::new())),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct App;
|
struct App {
|
||||||
|
data: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
data: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
fn update(&mut self, ctx: &Context, frame: &mut Frame) {
|
fn update(&mut self, ctx: &Context, _frame: &mut Frame) {
|
||||||
let code = QrCode::new(b"hello").unwrap();
|
TopBottomPanel::top("main").show(ctx, |ui| TextEdit::singleline(&mut self.data).ui(ui));
|
||||||
CentralPanel::default().show(ctx, |ui| {
|
CentralPanel::default().show(ctx, |ui| {
|
||||||
QrCodeWidget::new(&code).ui(ui);
|
if let Ok(q) = QrCodeWidget::from_data(self.data.as_bytes()) {
|
||||||
|
q.ui(ui)
|
||||||
|
} else {
|
||||||
|
ui.label("Invalid data")
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
61
src/lib.rs
61
src/lib.rs
@ -1,13 +1,28 @@
|
|||||||
use egui::{vec2, Color32, Rect, Response, Rounding, Sense, Stroke, Ui, Widget};
|
use egui::{vec2, Color32, Rect, Response, Rounding, Sense, Stroke, Ui, Widget};
|
||||||
|
use qrcode::types::QrError;
|
||||||
use qrcode::{Color, QrCode};
|
use qrcode::{Color, QrCode};
|
||||||
|
|
||||||
|
enum CodeSrc<'a> {
|
||||||
|
Ref(&'a QrCode),
|
||||||
|
Owned(QrCode),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct QrCodeWidget<'a> {
|
pub struct QrCodeWidget<'a> {
|
||||||
code: &'a QrCode,
|
code: CodeSrc<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> QrCodeWidget<'a> {
|
impl<'a> QrCodeWidget<'a> {
|
||||||
pub fn new(code: &'a QrCode) -> Self {
|
pub fn new(code: &'a QrCode) -> Self {
|
||||||
QrCodeWidget { code }
|
QrCodeWidget {
|
||||||
|
code: CodeSrc::Ref(code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_data(data: &[u8]) -> Result<Self, QrError> {
|
||||||
|
let code = QrCode::new(data)?;
|
||||||
|
Ok(QrCodeWidget {
|
||||||
|
code: CodeSrc::Owned(code),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,25 +30,39 @@ impl Widget for QrCodeWidget<'_> {
|
|||||||
fn ui(self, ui: &mut Ui) -> Response {
|
fn ui(self, ui: &mut Ui) -> Response {
|
||||||
let size = ui.available_size();
|
let size = ui.available_size();
|
||||||
|
|
||||||
let (response, painter) = ui.allocate_painter(size, Sense::click());
|
let code_ref = match &self.code {
|
||||||
let w = self.code.width();
|
CodeSrc::Ref(code) => code,
|
||||||
let start = response.rect.min;
|
CodeSrc::Owned(q) => q,
|
||||||
|
};
|
||||||
|
let w = code_ref.width();
|
||||||
|
let scale = (size.x.min(size.y) / w as f32).floor();
|
||||||
|
let start = ui.cursor().min;
|
||||||
|
let (response, painter) =
|
||||||
|
ui.allocate_painter(vec2(w as f32 * scale, w as f32 * scale), Sense::click());
|
||||||
|
|
||||||
|
painter.rect(
|
||||||
|
response.rect,
|
||||||
|
Rounding::none(),
|
||||||
|
Color32::WHITE,
|
||||||
|
Stroke::NONE,
|
||||||
|
);
|
||||||
let mut ctr = 0;
|
let mut ctr = 0;
|
||||||
let scale = (size.x / w as f32).floor();
|
for c in code_ref.to_colors() {
|
||||||
for c in self.code.to_colors() {
|
|
||||||
let row = ctr / w;
|
let row = ctr / w;
|
||||||
let col = ctr % w;
|
let col = ctr % w;
|
||||||
let c_start = start + vec2(col as f32 * scale, row as f32 * scale);
|
let c_start = start + vec2(col as f32 * scale, row as f32 * scale);
|
||||||
let c_end = c_start + vec2(scale, scale);
|
let c_end = c_start + vec2(scale, scale);
|
||||||
painter.rect(
|
if matches!(c, Color::Dark) {
|
||||||
Rect::from_min_max(c_start, c_end),
|
painter.rect(
|
||||||
Rounding::none(),
|
Rect::from_min_max(c_start, c_end),
|
||||||
match c {
|
Rounding::none(),
|
||||||
Color::Light => Color32::WHITE,
|
match c {
|
||||||
Color::Dark => Color32::BLACK,
|
Color::Light => Color32::WHITE,
|
||||||
},
|
Color::Dark => Color32::BLACK,
|
||||||
Stroke::NONE,
|
},
|
||||||
);
|
Stroke::NONE,
|
||||||
|
);
|
||||||
|
}
|
||||||
ctr += 1;
|
ctr += 1;
|
||||||
}
|
}
|
||||||
response
|
response
|
||||||
|
Loading…
x
Reference in New Issue
Block a user