1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
use crate::{
    graphics::FloatRect,
    sf_box::{Dispose, RawDefault},
    system::Vector2f,
    SfBox,
};
use csfml_graphics_sys as ffi;
use std::borrow::ToOwned;

/// 2D camera that defines what region is shown on screen
///
/// This is a very powerful concept: you can scroll,
/// rotate or zoom the entire scene without altering
/// the way that your drawable objects are drawn.
#[derive(Debug)]
#[allow(missing_copy_implementations)]
#[repr(C)]
pub struct View {
    _opaque: [u8; 0],
}

impl View {
    /// Get the current orientation of a view
    ///
    /// Return the rotation angle of the view, in degrees
    #[must_use]
    pub fn rotation(&self) -> f32 {
        unsafe { ffi::sfView_getRotation(self.raw()) }
    }
    /// Get the center of a view
    ///
    /// Return the center of the view
    #[must_use]
    pub fn center(&self) -> Vector2f {
        unsafe { Vector2f::from_raw(ffi::sfView_getCenter(self.raw())) }
    }

    /// Get the size of a view
    ///
    /// Return the size of the view
    #[must_use]
    pub fn size(&self) -> Vector2f {
        unsafe { Vector2f::from_raw(ffi::sfView_getSize(self.raw())) }
    }

    /// Get the target viewport rectangle of a view
    ///
    /// Return the viewport rectangle, expressed as a factor of the target size
    #[must_use]
    pub fn viewport(&self) -> FloatRect {
        unsafe { FloatRect::from_raw(ffi::sfView_getViewport(self.raw())) }
    }
    /// Creates a view with position and size
    ///
    /// # Arguments
    /// * center - The center of the view
    /// * size - The size of the view
    #[must_use]
    pub fn new(center: Vector2f, size: Vector2f) -> SfBox<View> {
        let mut view: SfBox<View> = Default::default();
        view.set_center(center);
        view.set_size(size);
        view
    }

    /// Construct a view from a rectangle
    ///
    /// # Arguments
    /// * rectangle - The rectangle defining the zone to display
    #[must_use]
    pub fn from_rect(rectangle: &FloatRect) -> SfBox<View> {
        let view = unsafe { ffi::sfView_createFromRect(rectangle.raw()) };
        SfBox::new(view as *mut Self).expect("Failed to create View from Rect")
    }

    /// Set the orientation of a view
    ///
    /// The default rotation of a view is 0 degree.
    ///
    /// # Arguments
    /// * angle - New angle, in degrees
    pub fn set_rotation(&mut self, angle: f32) {
        unsafe { ffi::sfView_setRotation(self.raw_mut(), angle) }
    }

    /// Rotate a view relatively to its current orientation
    ///
    /// # Arguments
    /// * angle - Angle to rotate, in degrees
    pub fn rotate(&mut self, angle: f32) {
        unsafe { ffi::sfView_rotate(self.raw_mut(), angle) }
    }

    /// Resize a view rectangle relatively to its current size
    ///
    /// Resizing the view simulates a zoom, as the zone displayed
    /// on screen grows or shrinks.
    ///
    /// # factor is a multiplier:
    /// * 1 keeps the size unchanged
    /// * bigger than 1 makes the view bigger (objects appear smaller)
    /// * smaller than 1 makes the view smaller (objects appear bigger)
    ///
    /// # Arguments
    /// * factor - Zoom factor to apply
    pub fn zoom(&mut self, factor: f32) {
        unsafe { ffi::sfView_zoom(self.raw_mut(), factor) }
    }

    /// Set the center of a view
    ///
    /// # Arguments
    /// * center - New center
    pub fn set_center<C: Into<Vector2f>>(&mut self, center: C) {
        unsafe { ffi::sfView_setCenter(self.raw_mut(), center.into().raw()) }
    }

    /// Set the size of a view
    ///
    /// # Arguments
    /// * size - New size of the view
    pub fn set_size<S: Into<Vector2f>>(&mut self, size: S) {
        unsafe { ffi::sfView_setSize(self.raw_mut(), size.into().raw()) }
    }

    /// Move a view relatively to its current position
    ///
    /// # Arguments
    /// * offset - Offset
    pub fn move_<O: Into<Vector2f>>(&mut self, offset: O) {
        unsafe { ffi::sfView_move(self.raw_mut(), offset.into().raw()) }
    }

    /// Set the target viewport of a view
    ///
    /// The viewport is the rectangle into which the contents of the
    /// view are displayed, expressed as a factor (between 0 and 1)
    /// of the size of the render target to which the view is applied.
    /// For example, a view which takes the left side of the target would
    /// be defined by a rect of (0, 0, 0.5, 1).
    /// By default, a view has a viewport which covers the entire target.
    ///
    /// # Arguments
    /// * viewport - New viewport rectangle
    pub fn set_viewport(&mut self, viewport: &FloatRect) {
        unsafe { ffi::sfView_setViewport(self.raw_mut(), viewport.raw()) }
    }

    /// Reset a view to the given rectangle
    ///
    /// Note that this function resets the rotation angle to 0.
    ///
    /// # Arguments
    /// * rectangle - Rectangle defining the zone to display
    pub fn reset(&mut self, rectangle: &FloatRect) {
        unsafe { ffi::sfView_reset(self.raw_mut(), rectangle.raw()) }
    }
    pub(super) fn raw(&self) -> *const ffi::sfView {
        let ptr: *const Self = self;
        ptr as _
    }
    fn raw_mut(&mut self) -> *mut ffi::sfView {
        let ptr: *mut Self = self;
        ptr as _
    }
}

impl ToOwned for View {
    type Owned = SfBox<Self>;
    fn to_owned(&self) -> Self::Owned {
        let view = unsafe { ffi::sfView_copy(self.raw()) };
        SfBox::new(view as *mut Self).expect("Failed to copy View")
    }
}

impl RawDefault for View {
    fn raw_default() -> *mut Self {
        let view = unsafe { ffi::sfView_create() };
        view as _
    }
}

impl Dispose for View {
    unsafe fn dispose(&mut self) {
        let ptr: *mut Self = self;
        ffi::sfView_destroy(ptr as _)
    }
}