@@ -6,6 +6,10 @@ use std::{
6
6
7
7
use crate :: prelude:: * ;
8
8
9
+ mod offset;
10
+
11
+ pub use offset:: * ;
12
+
9
13
/// A simple rectangle used in the computation of the layout and to give widgets a hint about the
10
14
/// area they are supposed to render to.
11
15
#[ derive( Debug , Default , Clone , Copy , Eq , PartialEq , Hash ) ]
@@ -106,6 +110,26 @@ impl Rect {
106
110
}
107
111
}
108
112
113
+ /// Moves the `Rect` without modifying its size.
114
+ ///
115
+ /// Moves the `Rect` according to the given offset without modifying its [`width`](Rect::width)
116
+ /// or [`height`](Rect::height).
117
+ /// - Positive `x` moves the whole `Rect` to the right, negative to the left.
118
+ /// - Positive `y` moves the whole `Rect` to the bottom, negative to the top.
119
+ ///
120
+ /// See [`Offset`] for details.
121
+ pub fn offset ( self , offset : Offset ) -> Rect {
122
+ Rect {
123
+ x : i32:: from ( self . x )
124
+ . saturating_add ( offset. x )
125
+ . clamp ( 0 , ( u16:: MAX - self . width ) as i32 ) as u16 ,
126
+ y : i32:: from ( self . y )
127
+ . saturating_add ( offset. y )
128
+ . clamp ( 0 , ( u16:: MAX - self . height ) as i32 ) as u16 ,
129
+ ..self
130
+ }
131
+ }
132
+
109
133
/// Returns a new rect that contains both the current one and the given one.
110
134
pub fn union ( self , other : Rect ) -> Rect {
111
135
let x1 = min ( self . x , other. x ) ;
@@ -207,6 +231,39 @@ mod tests {
207
231
) ;
208
232
}
209
233
234
+ #[ test]
235
+ fn offset ( ) {
236
+ assert_eq ! (
237
+ Rect :: new( 1 , 2 , 3 , 4 ) . offset( Offset { x: 5 , y: 6 } ) ,
238
+ Rect :: new( 6 , 8 , 3 , 4 ) ,
239
+ ) ;
240
+ }
241
+
242
+ #[ test]
243
+ fn negative_offset ( ) {
244
+ assert_eq ! (
245
+ Rect :: new( 4 , 3 , 3 , 4 ) . offset( Offset { x: -2 , y: -1 } ) ,
246
+ Rect :: new( 2 , 2 , 3 , 4 ) ,
247
+ ) ;
248
+ }
249
+
250
+ #[ test]
251
+ fn negative_offset_saturate ( ) {
252
+ assert_eq ! (
253
+ Rect :: new( 1 , 2 , 3 , 4 ) . offset( Offset { x: -5 , y: -6 } ) ,
254
+ Rect :: new( 0 , 0 , 3 , 4 ) ,
255
+ ) ;
256
+ }
257
+
258
+ /// Offsets a [`Rect`] making it go outside [`u16::MAX`], it should keep its size.
259
+ #[ test]
260
+ fn offset_saturate_max ( ) {
261
+ assert_eq ! (
262
+ Rect :: new( u16 :: MAX - 500 , u16 :: MAX - 500 , 100 , 100 ) . offset( Offset { x: 1000 , y: 1000 } ) ,
263
+ Rect :: new( u16 :: MAX - 100 , u16 :: MAX - 100 , 100 , 100 ) ,
264
+ ) ;
265
+ }
266
+
210
267
#[ test]
211
268
fn union ( ) {
212
269
assert_eq ! (
0 commit comments