Commit 65484606 authored by Jeremy Soller's avatar Jeremy Soller

Initial HiDPI support

parent 12ae4a2e
Pipeline #5880 failed with stage
in 1 minute and 51 seconds
......@@ -199,15 +199,50 @@ impl Image {
}
pub fn from_path<P: AsRef<Path>>(path: P) -> Option<Image> {
Image::from_path_scale(path, 1)
}
pub fn from_path_scale<P: AsRef<Path>>(path: P, scale: i32) -> Option<Image> {
match orbimage::Image::from_path(path) {
Ok(orb_image) => {
let width = orb_image.width();
let height = orb_image.height();
let data = orb_image.into_data();
Some(Image::from_data(width as i32, height as i32, unsafe { mem::transmute(data) }))
if scale == 1 {
Some(Image::from_data(
width as i32, height as i32,
unsafe { mem::transmute(data) }
))
} else if scale > 1 {
let mut new_data = vec![
Color::rgb(0, 0, 0);
data.len() * (scale * scale) as usize
].into_boxed_slice();
for y in 0..height as i32 {
for x in 0..width as i32 {
let i = y * width as i32 + x;
let value = data[i as usize].data;
for y_s in 0..scale {
for x_s in 0..scale {
let new_i = (y * scale + y_s) * width as i32 * scale + x * scale + x_s;
new_data[new_i as usize].data = value;
}
}
}
}
Some(Image::from_data(
width as i32 * scale, height as i32 * scale,
unsafe { mem::transmute(new_data) }
))
} else {
println!("orbital Image::from_path_scale: scale {} < 1", scale);
None
}
},
Err(err) => {
println!("orbital Image::from_path: {}", err);
println!("orbital Image::from_path_scale: {}", err);
None
}
}
......
......@@ -90,24 +90,27 @@ pub struct OrbitalScheme {
redraws: Vec<Rect>,
font: orbfont::Font,
clipboard: Vec<u8>,
scale: i32,
}
impl OrbitalScheme {
pub fn new(width: i32, height: i32, config: &Config) -> OrbitalScheme {
let scale = (height / 1600) + 1;
let mut cursors = BTreeMap::new();
cursors.insert(CursorKind::None, Image::new(0, 0));
cursors.insert(CursorKind::LeftPtr, Image::from_path(&config.cursor).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::BottomLeftCorner, Image::from_path(&config.bottom_left_corner).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::BottomRightCorner, Image::from_path(&config.bottom_right_corner).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::BottomSide, Image::from_path(&config.bottom_side).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::LeftSide, Image::from_path(&config.left_side).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::RightSide, Image::from_path(&config.right_side).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::LeftPtr, Image::from_path_scale(&config.cursor, scale).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::BottomLeftCorner, Image::from_path_scale(&config.bottom_left_corner, scale).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::BottomRightCorner, Image::from_path_scale(&config.bottom_right_corner, scale).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::BottomSide, Image::from_path_scale(&config.bottom_side, scale).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::LeftSide, Image::from_path_scale(&config.left_side, scale).unwrap_or(Image::new(0, 0)));
cursors.insert(CursorKind::RightSide, Image::from_path_scale(&config.right_side, scale).unwrap_or(Image::new(0, 0)));
OrbitalScheme {
window_max: Image::from_path(&config.window_max).unwrap_or(Image::new(0, 0)),
window_max_unfocused: Image::from_path(&config.window_max_unfocused).unwrap_or(Image::new(0, 0)),
window_close: Image::from_path(&config.window_close).unwrap_or(Image::new(0, 0)),
window_close_unfocused: Image::from_path(&config.window_close_unfocused).unwrap_or(Image::new(0, 0)),
window_max: Image::from_path_scale(&config.window_max, scale).unwrap_or(Image::new(0, 0)),
window_max_unfocused: Image::from_path_scale(&config.window_max_unfocused, scale).unwrap_or(Image::new(0, 0)),
window_close: Image::from_path_scale(&config.window_close, scale).unwrap_or(Image::new(0, 0)),
window_close_unfocused: Image::from_path_scale(&config.window_close_unfocused, scale).unwrap_or(Image::new(0, 0)),
cursors: cursors,
cursor_i: CursorKind::LeftPtr,
cursor_x: 0,
......@@ -128,6 +131,7 @@ impl OrbitalScheme {
redraws: vec![Rect::new(0, 0, width, height)],
font: orbfont::Font::find(Some("Sans"), None, None).unwrap(),
clipboard: Vec::new(),
scale,
}
}
......@@ -447,6 +451,8 @@ impl<'a> OrbitalSchemeEvent<'a> {
/// Draws a list of currently open windows in the middle of the screen
fn draw_window_list(&mut self) {
//TODO: HiDPI
let mut rendered_text: Vec<orbfont::Text> = vec![];
for id in self.scheme.order.iter() {
if let Some(window) = self.scheme.windows.get(&id) {
......@@ -1068,7 +1074,7 @@ impl<'a> OrbitalSchemeEvent<'a> {
}
}
let mut window = Window::new(x, y, width, height);
let mut window = Window::new(x, y, width, height, self.scheme.scale);
for flag in flags.chars() {
match flag {
......
......@@ -21,6 +21,7 @@ pub enum WindowZOrder {
pub struct Window {
pub x: i32,
pub y: i32,
pub scale: i32,
pub title: String,
pub async: bool,
pub borderless: bool,
......@@ -42,10 +43,11 @@ pub struct Window {
}
impl Window {
pub fn new(x: i32, y: i32, w: i32, h: i32) -> Window {
pub fn new(x: i32, y: i32, w: i32, h: i32, scale: i32) -> Window {
Window {
x: x,
y: y,
x,
y,
scale,
title: String::new(),
async: false,
borderless: false,
......@@ -83,13 +85,13 @@ impl Window {
if self.borderless {
Rect::new(-1, -1, 0, 0)
} else {
Rect::new(self.x, self.y - 28, self.width(), 28)
Rect::new(self.x, self.y - 28 * self.scale, self.width(), 28 * self.scale)
}
}
pub fn bottom_border_rect(&self) -> Rect {
if self.resizable {
Rect::new(self.x, self.y + self.height(), self.width(), 8)
Rect::new(self.x, self.y + self.height(), self.width(), 8 * self.scale)
} else {
Rect::new(-1, -1, 0, 0)
}
......@@ -97,7 +99,7 @@ impl Window {
pub fn bottom_left_border_rect(&self) -> Rect {
if self.resizable {
Rect::new(self.x - 8, self.y + self.height(), 8, 8)
Rect::new(self.x - 8 * self.scale, self.y + self.height(), 8 * self.scale, 8 * self.scale)
} else {
Rect::new(-1, -1, 0, 0)
}
......@@ -105,7 +107,7 @@ impl Window {
pub fn bottom_right_border_rect(&self) -> Rect {
if self.resizable {
Rect::new(self.x + self.width(), self.y + self.height(), 8, 8)
Rect::new(self.x + self.width(), self.y + self.height(), 8 * self.scale, 8 * self.scale)
} else {
Rect::new(-1, -1, 0, 0)
}
......@@ -113,7 +115,7 @@ impl Window {
pub fn left_border_rect(&self) -> Rect {
if self.resizable {
Rect::new(self.x - 8, self.y, 8, self.height())
Rect::new(self.x - 8 * self.scale, self.y, 8 * self.scale, self.height())
} else {
Rect::new(-1, -1, 0, 0)
}
......@@ -121,18 +123,18 @@ impl Window {
pub fn right_border_rect(&self) -> Rect {
if self.resizable {
Rect::new(self.x + self.width(), self.y, 8, self.height())
Rect::new(self.x + self.width(), self.y, 8 * self.scale, self.height())
} else {
Rect::new(-1, -1, 0, 0)
}
}
pub fn max_contains(&self, x: i32, y: i32) -> bool {
! self.borderless && x >= max(self.x + 6, self.x + self.width() - 36) && y >= self.y - 28 && x < self.x + self.width() - 18 && y < self.y
! self.borderless && x >= max(self.x + 6 * self.scale, self.x + self.width() - 36 * self.scale) && y >= self.y - 28 * self.scale && x < self.x + self.width() - 18 * self.scale && y < self.y
}
pub fn close_contains(&self, x: i32, y: i32) -> bool {
! self.borderless && x >= max(self.x + 6, self.x + self.width() - 18) && y >= self.y - 28 && x < self.x + self.width() && y < self.y
! self.borderless && x >= max(self.x + 6 * self.scale, self.x + self.width() - 18 * self.scale) && y >= self.y - 28 * self.scale && x < self.x + self.width() && y < self.y
}
pub fn draw_title(&mut self, image: &mut ImageRef, rect: &Rect, focused: bool, window_max: &mut Image, window_close: &mut Image) {
......@@ -143,11 +145,11 @@ impl Window {
title_intersect.width() as u32, title_intersect.height() as u32,
if focused { BAR_HIGHLIGHT_COLOR } else { BAR_COLOR });
let mut x = self.x + 6;
let w = max(self.x + 6, self.x + self.width() - 18) - x;
let mut x = self.x + 6 * self.scale;
let w = max(self.x + 6 * self.scale, self.x + self.width() - 18 * self.scale) - x;
if w > 0 {
let title_image = if focused { &mut self.title_image } else { &mut self.title_image_unfocused };
let image_rect = Rect::new(x, title_rect.top() + 6, min(w, title_image.width()), title_image.height());
let image_rect = Rect::new(x, title_rect.top() + 6 * self.scale, min(w, title_image.width()), title_image.height());
let image_intersect = rect.intersection(&image_rect);
if ! image_intersect.is_empty() {
image.roi(&image_intersect).blend(&title_image.roi(&image_intersect.offset(-image_rect.left(), -image_rect.top())));
......@@ -155,9 +157,9 @@ impl Window {
}
if self.resizable {
x = max(self.x + 6, self.x + self.width() - 36);
if x + 36 <= self.x + self.width() {
let image_rect = Rect::new(x, title_rect.top() + 7, window_max.width(), window_max.height());
x = max(self.x + 6, self.x + self.width() - 36 * self.scale);
if x + 36 * self.scale <= self.x + self.width() {
let image_rect = Rect::new(x, title_rect.top() + 7 * self.scale, window_max.width(), window_max.height());
let image_intersect = rect.intersection(&image_rect);
if ! image_intersect.is_empty() {
image.roi(&image_intersect).blend(&window_max.roi(&image_intersect.offset(-image_rect.left(), -image_rect.top())));
......@@ -166,9 +168,9 @@ impl Window {
}
if !self.unclosable {
x = max(self.x + 6, self.x + self.width() - 18);
if x + 18 <= self.x + self.width() {
let image_rect = Rect::new(x, title_rect.top() + 7, window_close.width(), window_close.height());
x = max(self.x + 6 * self.scale, self.x + self.width() - 18 * self.scale);
if x + 18 * self.scale <= self.x + self.width() {
let image_rect = Rect::new(x, title_rect.top() + 7 * self.scale, window_close.width(), window_close.height());
let image_intersect = rect.intersection(&image_rect);
if ! image_intersect.is_empty() {
image.roi(&image_intersect).blend(&window_close.roi(&image_intersect.offset(-image_rect.left(), -image_rect.top())));
......@@ -226,7 +228,7 @@ impl Window {
}
pub fn render_title(&mut self, font: &Font) {
let title_render = font.render(&self.title, 16.0);
let title_render = font.render(&self.title, (16 * self.scale) as f32);
self.title_image = Image::from_color(title_render.width() as i32, title_render.height() as i32, BAR_HIGHLIGHT_COLOR);
title_render.draw(&mut self.title_image, 0, 0, TEXT_HIGHLIGHT_COLOR);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment