@@ -29,6 +29,7 @@ pub struct Button {
29
29
small : bool ,
30
30
frame : Option < bool > ,
31
31
min_size : Vec2 ,
32
+ image : Option < widgets:: Image > ,
32
33
}
33
34
34
35
impl Button {
@@ -42,6 +43,27 @@ impl Button {
42
43
small : false ,
43
44
frame : None ,
44
45
min_size : Vec2 :: ZERO ,
46
+ image : None ,
47
+ }
48
+ }
49
+
50
+ /// Creates a button with an image to the left of the text. The size of the image as displayed is defined by the size Vec2 provided.
51
+ #[ allow( clippy:: needless_pass_by_value) ]
52
+ pub fn image_and_text (
53
+ texture_id : TextureId ,
54
+ size : impl Into < Vec2 > ,
55
+ text : impl Into < WidgetText > ,
56
+ ) -> Self {
57
+ Self {
58
+ text : text. into ( ) ,
59
+ fill : None ,
60
+ stroke : None ,
61
+ sense : Sense :: click ( ) ,
62
+ small : false ,
63
+ frame : None ,
64
+ wrap : None ,
65
+ min_size : Vec2 :: ZERO ,
66
+ image : Some ( widgets:: Image :: new ( texture_id, size) ) ,
45
67
}
46
68
}
47
69
@@ -123,6 +145,7 @@ impl Widget for Button {
123
145
small,
124
146
frame,
125
147
min_size,
148
+ image,
126
149
} = self ;
127
150
128
151
let frame = frame. unwrap_or_else ( || ui. visuals ( ) . button_frame ) ;
@@ -142,15 +165,27 @@ impl Widget for Button {
142
165
}
143
166
desired_size = desired_size. at_least ( min_size) ;
144
167
168
+ if let Some ( image) = image {
169
+ desired_size. x += image. size ( ) . x + ui. spacing ( ) . icon_spacing ;
170
+ desired_size. y = desired_size. y . max ( image. size ( ) . y + 2.0 * button_padding. y ) ;
171
+ }
172
+
145
173
let ( rect, response) = ui. allocate_at_least ( desired_size, sense) ;
146
174
response. widget_info ( || WidgetInfo :: labeled ( WidgetType :: Button , text. text ( ) ) ) ;
147
175
148
176
if ui. is_rect_visible ( rect) {
149
177
let visuals = ui. style ( ) . interact ( & response) ;
150
- let text_pos = ui
151
- . layout ( )
152
- . align_size_within_rect ( text. size ( ) , rect. shrink2 ( button_padding) )
153
- . min ;
178
+ let text_pos = if let Some ( image) = image {
179
+ let icon_spacing = ui. spacing ( ) . icon_spacing ;
180
+ pos2 (
181
+ rect. min . x + button_padding. x + image. size ( ) . x + icon_spacing,
182
+ rect. center ( ) . y - 0.5 * text. size ( ) . y ,
183
+ )
184
+ } else {
185
+ ui. layout ( )
186
+ . align_size_within_rect ( text. size ( ) , rect. shrink2 ( button_padding) )
187
+ . min
188
+ } ;
154
189
155
190
if frame {
156
191
let fill = fill. unwrap_or ( visuals. bg_fill ) ;
@@ -166,6 +201,14 @@ impl Widget for Button {
166
201
text. paint_with_visuals ( ui. painter ( ) , text_pos, visuals) ;
167
202
}
168
203
204
+ if let Some ( image) = image {
205
+ let image_rect = Rect :: from_min_size (
206
+ pos2 ( rect. min . x , rect. center ( ) . y - 0.5 - ( image. size ( ) . y / 2.0 ) ) ,
207
+ image. size ( ) ,
208
+ ) ;
209
+ image. paint_at ( ui, image_rect) ;
210
+ }
211
+
169
212
response
170
213
}
171
214
}
0 commit comments