From ace47d3225b7a641f2182686fcd2abe66d8e4ed2 Mon Sep 17 00:00:00 2001 From: Emi Simpson Date: Sat, 8 Jan 2022 18:54:24 -0500 Subject: [PATCH] Give the editor a bit of a facelift --- fonts/vg5000/SIL Open Font License.txt | 103 +++++++++++++++++++++++++ fonts/vg5000/VG5000.otf | 3 + src/editor.rs | 2 +- src/lyrics.rs | 39 +++++++--- src/styles.rs | 51 +++++++++++- 5 files changed, 183 insertions(+), 15 deletions(-) create mode 100755 fonts/vg5000/SIL Open Font License.txt create mode 100644 fonts/vg5000/VG5000.otf diff --git a/fonts/vg5000/SIL Open Font License.txt b/fonts/vg5000/SIL Open Font License.txt new file mode 100755 index 0000000..fd9b59c --- /dev/null +++ b/fonts/vg5000/SIL Open Font License.txt @@ -0,0 +1,103 @@ +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +SIL Open Font License v1.1 +==================================================== + + +Preamble +---------- + +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + + +Definitions +------------- + +`"Font Software"` refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +`"Reserved Font Name"` refers to any names specified as such after the +copyright statement(s). + +`"Original Version"` refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +`"Modified Version"` refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +`"Author"` refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + + +Permission & Conditions +------------------------ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1. Neither the Font Software nor any of its individual components, + in Original or Modified Versions, may be sold by itself. + +2. Original or Modified Versions of the Font Software may be bundled, + redistributed and/or sold with any software, provided that each copy + contains the above copyright notice and this license. These can be + included either as stand-alone text files, human-readable headers or + in the appropriate machine-readable metadata fields within text or + binary files as long as those fields can be easily viewed by the user. + +3. No Modified Version of the Font Software may use the Reserved Font + Name(s) unless explicit written permission is granted by the corresponding + Copyright Holder. This restriction only applies to the primary font name as + presented to the users. + +4. The name(s) of the Copyright Holder(s) or the Author(s) of the Font + Software shall not be used to promote, endorse or advertise any + Modified Version, except to acknowledge the contribution(s) of the + Copyright Holder(s) and the Author(s) or with their explicit written + permission. + +5. The Font Software, modified or unmodified, in part or in whole, + must be distributed entirely under this license, and must not be + distributed under any other license. The requirement for fonts to + remain under this license does not apply to any document created + using the Font Software. + + +Termination +----------- + +This license becomes null and void if any of the above conditions are +not met. + + + DISCLAIMER + + THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE + COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL + DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM + OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/vg5000/VG5000.otf b/fonts/vg5000/VG5000.otf new file mode 100644 index 0000000..9ca9143 --- /dev/null +++ b/fonts/vg5000/VG5000.otf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed108405cbd07019ea9f82d7ebd9c7add492a048d5ded2145a75a9f0b36208ae +size 75176 diff --git a/src/editor.rs b/src/editor.rs index d40bc44..c25c3c9 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -43,7 +43,7 @@ impl Editor { let cover = cover.expect("TODO"); #[cfg(not(debug_assertions))] - let cover = cover.blur((cover.width() / 50) as f32); + let cover = cover.blur((cover.width() / 100) as f32); let bg_img = DynamicImage::ImageBgra8(cover.into_bgra8()); diff --git a/src/lyrics.rs b/src/lyrics.rs index 7b2675b..dbd23b7 100644 --- a/src/lyrics.rs +++ b/src/lyrics.rs @@ -1,3 +1,4 @@ +use iced::Space; use iced_native::text_input::Value; use core::ops::RangeInclusive; use core::time::Duration; @@ -6,7 +7,7 @@ use iced::Text; use iced::Container; use iced::Length; use iced::Element; -use crate::styles::Theme; +use crate::styles::{Theme, FONT_VG5000}; use crate::app::Message; use iced::widget::text_input::{self, TextInput}; @@ -122,11 +123,16 @@ impl Lyrics { pub fn view(&mut self, theme: Theme) -> Element { let is_sole_line = self.lines.len() == 1; + let spacers = ( + Space::new(Length::Fill, Length::Units(30)), + Space::new(Length::Fill, Length::Units(30)), + ); let scroller = self.lines.iter_mut() .enumerate() .map(|(i, l)| l.view(is_sole_line, i, theme)) - .fold(Scrollable::new(&mut self.scroll_state), |s, l| s.push(l)) + .fold(Scrollable::new(&mut self.scroll_state).push(spacers.0), |s, l| s.push(l)) + .push(spacers.1) .width(Length::Fill) .align_items(Align::Center); @@ -165,6 +171,12 @@ impl Lyric { pub fn view(&mut self, show_placeholder: bool, line_no: usize, theme: Theme) -> Element { + const SMALL_SIZE: u16 = 20; + const LARGE_SIZE: u16 = 25; + const TIMESTAMP_W: u16 = 67; + const LINE_HEIGHT: u16 = 26; + const TOTAL_W: u16 = 400; + let is_focused = self.is_selected(); let placeholder = if show_placeholder { @@ -173,7 +185,7 @@ impl Lyric { "..." } else { "" }; - let size = if is_focused { 30 } else { 20 }; + let size = if is_focused { LARGE_SIZE } else { SMALL_SIZE }; let timestamp_input = TextInput::new( &mut self.timestamp_state, @@ -182,9 +194,10 @@ impl Lyric { move|new_value| LyricEvent::TimestampChanged(new_value).into_msg(line_no), ) .style(theme) - .size(size - 5) - .width(Length::Units(97)) + .size(SMALL_SIZE) + .width(Length::Units(TIMESTAMP_W)) .on_submit(LyricEvent::LineAdvanced.into_msg(line_no)) + .font(FONT_VG5000) .into(); let text_input = TextInput::new( @@ -193,21 +206,27 @@ impl Lyric { &self.value, move|new_value| LyricEvent::LyricChanged(new_value).into_msg(line_no), ) - .style(theme) + .style(theme.active_lyric(is_focused)) .size(size) .width(Length::Fill) .on_submit(LyricEvent::LineAdvanced.into_msg(line_no)) + .font(FONT_VG5000) .into(); let l_bracket = Text::new("[") - .size(size) + .size(SMALL_SIZE) + .color(theme.reduced_text_color()) + .font(FONT_VG5000) .into(); - let r_bracket = Text::new("]") - .size(size) + let r_bracket = Text::new("] ") + .size(SMALL_SIZE) + .color(theme.reduced_text_color()) + .font(FONT_VG5000) .into(); Row::with_children(vec![l_bracket, timestamp_input, r_bracket, text_input]) - .width(Length::Units(400)) + .width(Length::Units(TOTAL_W)) + .height(Length::Units(LINE_HEIGHT)) .align_items(Align::Center) .into() } diff --git a/src/styles.rs b/src/styles.rs index 6e101b6..f4646c2 100644 --- a/src/styles.rs +++ b/src/styles.rs @@ -1,3 +1,4 @@ +use iced::Font; use image::Rgb; use crate::palette::Palette; use iced::Background; @@ -5,17 +6,53 @@ use iced::Color; use iced::widget::container; use iced::widget::text_input; +pub const FONT_VG5000: Font = Font::External { + name: "VG5000", + bytes: include_bytes!("../fonts/vg5000/VG5000.otf"), +}; + #[derive(Copy, Clone, Debug)] pub struct Theme { pub base_color: Color, pub text_color: Color, + subtype: Subtype, } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +enum Subtype { + Base, + ActiveLyric, +} +use Subtype::*; + impl Theme { pub fn from_palette(palette: Palette) -> Self { Theme { base_color: img_color_to_iced(palette.dominant_color()), text_color: Color::WHITE, + subtype: Base, + } + } + + pub fn reduced_text_color(&self) -> Color { + Color { + a: 0.5, + ..self.text_color + } + } + + pub fn active_lyric(&self, active: bool) -> Self { + if active { + self.set_subtype(ActiveLyric) + } else { + *self + } + } + + fn set_subtype(&self, subtype: Subtype) -> Self { + Theme { + subtype, + ..*self } } } @@ -25,6 +62,7 @@ impl Default for Theme { Theme { base_color: Color {r: 236. / 255., g: 63. / 255., b: 53. / 255., a: 1.}, text_color: Color {r: 1., g: 1., b: 1., a: 1.}, + subtype: Base, } } } @@ -54,13 +92,18 @@ impl text_input::StyleSheet for Theme { } fn placeholder_color(&self) -> Color { - let mut color = self.text_color; - color.a = 0.5; - color + Color { + a: 0.3, + ..self.text_color + } } fn value_color(&self) -> Color { - self.text_color + if self.subtype == ActiveLyric { + self.text_color + } else { + self.reduced_text_color() + } } fn selection_color(&self) -> Color {