11use egui:: {
2- Align , AtomExt , Button , Color32 , ImageSource , Layout , Pos2 , Sense , Ui , Vec2 , include_image,
3- pos2, vec2,
2+ Align , Button , Color32 , ImageSource , Layout , Pos2 , Sense , Ui , Vec2 , Widget , include_image, vec2,
43} ;
54
65#[ derive( Debug , Clone , Copy ) ]
@@ -16,14 +15,13 @@ pub struct PinInfo {
1615}
1716
1817pub struct GateGraphics {
18+ // TODO: Figure out what is the correct way to deal with images
1919 pub svg : ImageSource < ' static > ,
20- pub svg_path : & ' static str ,
2120 pub pins : & ' static [ PinInfo ] ,
2221}
2322
2423pub static NAND_GRAPHICS : GateGraphics = GateGraphics {
2524 svg : include_image ! ( "../assets/nand.svg" ) ,
26- svg_path : "file://assets/nand.svg" ,
2725 pins : & [
2826 PinInfo {
2927 kind : PinKind :: Input ,
@@ -55,14 +53,17 @@ pub struct GateInstance {
5553#[ derive( serde:: Deserialize , serde:: Serialize , Default ) ]
5654#[ serde( default ) ]
5755pub struct TemplateApp {
58- /// Currently dragged gate from palette
59- dragged_gate : Option < LogicGate > ,
56+ /// State
6057 /// Gates placed on the canvas
6158 canvas_gates : Vec < GateInstance > ,
62- /// Temporary drag position if dragging palette-gate
63- drag_position : Option < Pos2 > ,
6459 /// Next unique ID for gates
6560 next_gate_id : u32 ,
61+
62+ /// Dragging from panel
63+ panel_dragged_gate : Option < LogicGate > ,
64+ /// Temporary drag position if dragging palette-gate
65+ panel_drag_position : Option < Pos2 > ,
66+
6667 /// Currently dragged gate id from canvas
6768 dragged_canvas_gate : Option < u32 > ,
6869 /// Offset from mouse pointer to gate center at drag start
@@ -71,12 +72,6 @@ pub struct TemplateApp {
7172
7273impl TemplateApp {
7374 pub fn new ( cc : & eframe:: CreationContext < ' _ > ) -> Self {
74- // let texture = cc.egui_ctx.try_load_texture(
75- // NAND_GRAPHICS.svg_path,
76- // egui::TextureOptions::NEAREST,
77- // egui::SizeHint::default(),
78- // );
79- // Register all supported image loaders
8075 egui_extras:: install_image_loaders ( & cc. egui_ctx ) ;
8176 if let Some ( storage) = cc. storage {
8277 eframe:: get_value ( storage, eframe:: APP_KEY ) . unwrap_or_default ( )
@@ -100,54 +95,61 @@ impl TemplateApp {
10095 }
10196
10297 fn draw_palette ( & mut self , ui : & mut Ui ) {
103- // TODO: Figure out what is the correct way to deal with images
104- let svg_scaled = NAND_GRAPHICS . svg . clone ( ) ;
105- let response = ui . add ( egui :: ImageButton :: new ( svg_scaled ) . sense ( Sense :: click_and_drag ( ) ) ) ;
98+ let image = egui :: Image :: new ( NAND_GRAPHICS . svg . clone ( ) ) . max_height ( 70.0 ) ;
99+ let response = ui . add ( egui :: ImageButton :: new ( image ) . sense ( Sense :: click_and_drag ( ) ) ) ;
100+
106101 if response. drag_started ( ) {
107- self . dragged_gate = Some ( LogicGate :: Nand ) ;
108- self . drag_position = None ;
102+ self . panel_dragged_gate = Some ( LogicGate :: Nand ) ;
103+ self . panel_drag_position = None ;
109104 }
110105 if response. dragged ( ) {
111106 if let Some ( pointer_pos) = ui. ctx ( ) . pointer_interact_pos ( ) {
112- self . drag_position = Some ( pointer_pos) ;
107+ self . panel_drag_position = Some ( pointer_pos) ;
113108 }
114109 }
115- if ui. button ( "Clear Canvas" ) . clicked ( ) {
110+ if Button :: new ( "Clear Canvas" )
111+ . min_size ( vec2 ( 48.0 , 30.0 ) )
112+ . ui ( ui)
113+ . clicked ( )
114+ {
116115 self . canvas_gates . clear ( ) ;
117116 self . dragged_canvas_gate = None ;
118117 self . drag_offset = None ;
119118 }
120119 }
121120
122121 fn draw_canvas ( & mut self , ui : & mut Ui ) {
123- let ( resp, painter ) = ui. allocate_painter ( ui. available_size ( ) , Sense :: hover ( ) ) ;
122+ let ( resp, _painter ) = ui. allocate_painter ( ui. available_size ( ) , Sense :: hover ( ) ) ;
124123 let rect = resp. rect ;
125124
126125 // handle dragging from panel
127- if let ( Some ( gate_type) , Some ( pos) ) = ( & self . dragged_gate , self . drag_position ) {
126+ if let ( Some ( gate_type) , Some ( pos) ) = ( & self . panel_dragged_gate , self . panel_drag_position ) {
128127 if rect. contains ( pos) {
129128 Self :: draw_gate_svg_with_pins ( ui, gate_type, pos, Color32 :: YELLOW ) ;
130129 }
131130 }
132131
133132 // spawn a new gate
134- if let ( Some ( gate_type) , Some ( pos) ) = ( & self . dragged_gate , self . drag_position ) {
133+ if let ( Some ( gate_type) , Some ( pos) ) = ( & self . panel_dragged_gate , self . panel_drag_position ) {
135134 if rect. contains ( pos) && ui. ctx ( ) . input ( |i| i. pointer . any_released ( ) ) {
136135 self . canvas_gates . push ( GateInstance {
137136 id : self . next_gate_id ,
138137 gate_type : gate_type. clone ( ) ,
139138 position : pos,
140139 } ) ;
141140 self . next_gate_id += 1 ;
142- self . dragged_gate = None ;
143- self . drag_position = None ;
141+ self . panel_dragged_gate = None ;
142+ self . panel_drag_position = None ;
144143 }
145144 }
146145
147146 let pointer_pos = ui. input ( |i| i. pointer . interact_pos ( ) ) ;
148147 let pointer_pressed = ui. input ( |i| i. pointer . primary_down ( ) ) ;
149148 let pointer_any_up = ui. input ( |i| i. pointer . any_released ( ) ) ;
150- if self . dragged_gate . is_none ( ) && self . dragged_canvas_gate . is_none ( ) && pointer_pressed {
149+ if self . panel_dragged_gate . is_none ( )
150+ && self . dragged_canvas_gate . is_none ( )
151+ && pointer_pressed
152+ {
151153 if let Some ( mouse_pos) = pointer_pos {
152154 for gate in self . canvas_gates . iter ( ) . rev ( ) {
153155 let size = Vec2 :: new ( 48.0 , 36.0 ) ;
@@ -189,17 +191,15 @@ impl TemplateApp {
189191 }
190192
191193 fn draw_gate_svg_with_pins ( ui : & mut Ui , gate_type : & LogicGate , pos : Pos2 , _tint : Color32 ) {
192- let size = Vec2 :: new ( 48.0 , 36.0 ) ;
193- let rect = egui:: Rect :: from_center_size ( pos, size) ;
194-
195- match gate_type {
196- LogicGate :: Nand => {
197- ui. put ( rect, egui:: Image :: new ( NAND_GRAPHICS . svg . clone ( ) ) ) ;
198- }
199- }
200194 let graphics = match gate_type {
201195 LogicGate :: Nand => & NAND_GRAPHICS ,
202196 } ;
197+
198+ let size = Vec2 :: new ( 48.0 , 36.0 ) ;
199+ let rect = egui:: Rect :: from_center_size ( pos, size) ;
200+ let image = egui:: Image :: new ( graphics. svg . clone ( ) ) . fit_to_exact_size ( rect. size ( ) ) ;
201+ ui. put ( rect, image) ;
202+
203203 for pin in graphics. pins {
204204 let pin_pos = pos + pin. offset ;
205205 let color = match pin. kind {
0 commit comments