Add option to toggle ruler visibility (#1479)
* Sending Toggle Ruler message and setting visibility. Text and markers not working * Added resize on mount for Ruler Input * Set default for rulers_visible to pass test * Ruler Visibility portfolio wide instead of document * Sending Toggle Ruler message and setting visibility. Text and markers not working * Ruler Visibility portfolio wide instead of document * Cleanup * Reorganize the View menu bar; add toggle rulers hotkey * Remove non-working redundant bools, and make rulers set per-document --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
4fdf8410cf
commit
4fead6e7ec
|
|
@ -173,6 +173,7 @@ pub enum FrontendMessage {
|
|||
origin: (f64, f64),
|
||||
spacing: f64,
|
||||
interval: f64,
|
||||
visible: bool,
|
||||
},
|
||||
UpdateDocumentScrollbars {
|
||||
position: (f64, f64),
|
||||
|
|
|
|||
|
|
@ -343,6 +343,7 @@ pub fn default_mapping() -> Mapping {
|
|||
entry!(KeyDown(KeyI); modifiers=[Accel], action_dispatch=PortfolioMessage::Import),
|
||||
entry!(KeyDown(KeyX); modifiers=[Accel], action_dispatch=PortfolioMessage::Cut { clipboard: Clipboard::Device }),
|
||||
entry!(KeyDown(KeyC); modifiers=[Accel], action_dispatch=PortfolioMessage::Copy { clipboard: Clipboard::Device }),
|
||||
entry!(KeyDown(KeyR); modifiers=[Alt], action_dispatch=PortfolioMessage::ToggleRulers),
|
||||
//
|
||||
// FrontendMessage
|
||||
entry!(KeyDown(KeyV); modifiers=[Accel], action_dispatch=FrontendMessage::TriggerPaste),
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ use graphene_core::raster::ImageFrame;
|
|||
use glam::{DAffine2, DVec2};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Utility function for providing a default boolean value to serde.
|
||||
#[inline(always)]
|
||||
fn return_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct DocumentMessageHandler {
|
||||
pub document_legacy: DocumentLegacy,
|
||||
|
|
@ -43,6 +49,8 @@ pub struct DocumentMessageHandler {
|
|||
#[serde(skip)]
|
||||
pub snapping_state: SnappingState,
|
||||
pub overlays_visible: bool,
|
||||
#[serde(default = "return_true")]
|
||||
pub rulers_visible: bool,
|
||||
|
||||
#[serde(skip)]
|
||||
pub document_undo_history: VecDeque<DocumentSave>,
|
||||
|
|
@ -81,6 +89,7 @@ impl Default for DocumentMessageHandler {
|
|||
view_mode: ViewMode::default(),
|
||||
snapping_state: SnappingState::default(),
|
||||
overlays_visible: true,
|
||||
rulers_visible: true,
|
||||
|
||||
document_undo_history: VecDeque::new(),
|
||||
document_redo_history: VecDeque::new(),
|
||||
|
|
@ -614,6 +623,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
|||
origin: ruler_origin.into(),
|
||||
spacing: ruler_spacing,
|
||||
interval: ruler_interval,
|
||||
visible: self.rulers_visible,
|
||||
});
|
||||
}
|
||||
RenderScrollbars => {
|
||||
|
|
|
|||
|
|
@ -6,14 +6,15 @@ use crate::messages::prelude::*;
|
|||
#[derive(Debug, Clone, Default)]
|
||||
pub struct MenuBarMessageHandler {
|
||||
no_active_document: bool,
|
||||
rulers_hidden: bool,
|
||||
}
|
||||
|
||||
impl MessageHandler<MenuBarMessage, bool> for MenuBarMessageHandler {
|
||||
impl MessageHandler<MenuBarMessage, (bool, bool)> for MenuBarMessageHandler {
|
||||
#[remain::check]
|
||||
fn process_message(&mut self, message: MenuBarMessage, responses: &mut VecDeque<Message>, has_active_document: bool) {
|
||||
fn process_message(&mut self, message: MenuBarMessage, responses: &mut VecDeque<Message>, (has_active_document, rulers_hidden): (bool, bool)) {
|
||||
use MenuBarMessage::*;
|
||||
self.no_active_document = !has_active_document;
|
||||
|
||||
self.rulers_hidden = rulers_hidden;
|
||||
#[remain::sorted]
|
||||
match message {
|
||||
SendLayout => self.send_layout(responses, LayoutTarget::MenuBar),
|
||||
|
|
@ -289,8 +290,17 @@ impl LayoutHolder for MenuBarMessageHandler {
|
|||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
],
|
||||
vec![
|
||||
MenuBarEntry {
|
||||
label: "Zoom to Fit".into(),
|
||||
label: "Zoom to Fit Selection".into(),
|
||||
shortcut: action_keys!(NavigationMessageDiscriminant::FitViewportToSelection),
|
||||
action: MenuBarEntry::create_action(|_| NavigationMessage::FitViewportToSelection.into()),
|
||||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
},
|
||||
MenuBarEntry {
|
||||
label: "Zoom to Fit All".into(),
|
||||
shortcut: action_keys!(DocumentMessageDiscriminant::ZoomCanvasToFitAll),
|
||||
action: MenuBarEntry::create_action(|_| DocumentMessage::ZoomCanvasToFitAll.into()),
|
||||
disabled: no_active_document,
|
||||
|
|
@ -312,9 +322,10 @@ impl LayoutHolder for MenuBarMessageHandler {
|
|||
},
|
||||
],
|
||||
vec![MenuBarEntry {
|
||||
label: "Frame Selected".into(),
|
||||
shortcut: action_keys!(NavigationMessageDiscriminant::FitViewportToSelection),
|
||||
action: MenuBarEntry::create_action(|_| NavigationMessage::FitViewportToSelection.into()),
|
||||
label: "Rulers".into(),
|
||||
icon: Some(if self.rulers_hidden { "CheckboxUnchecked" } else { "CheckboxChecked" }.into()),
|
||||
shortcut: action_keys!(PortfolioMessageDiscriminant::ToggleRulers),
|
||||
action: MenuBarEntry::create_action(|_| PortfolioMessage::ToggleRulers.into()),
|
||||
disabled: no_active_document,
|
||||
..MenuBarEntry::default()
|
||||
}],
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ pub enum PortfolioMessage {
|
|||
document_id: u64,
|
||||
layer_path: Vec<LayerId>,
|
||||
},
|
||||
ToggleRulers,
|
||||
UpdateDocumentWidgets,
|
||||
UpdateOpenDocumentsList,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,13 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||
match message {
|
||||
// Sub-messages
|
||||
#[remain::unsorted]
|
||||
PortfolioMessage::MenuBar(message) => self.menu_bar_message_handler.process_message(message, responses, has_active_document),
|
||||
PortfolioMessage::MenuBar(message) => {
|
||||
if let Some(document_id) = self.active_document_id {
|
||||
if let Some(document) = self.documents.get_mut(&document_id) {
|
||||
self.menu_bar_message_handler.process_message(message, responses, (has_active_document, document.rulers_visible));
|
||||
}
|
||||
}
|
||||
}
|
||||
#[remain::unsorted]
|
||||
PortfolioMessage::Document(message) => {
|
||||
if let Some(document_id) = self.active_document_id {
|
||||
|
|
@ -517,6 +523,14 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||
});
|
||||
}
|
||||
}
|
||||
PortfolioMessage::ToggleRulers => {
|
||||
if let Some(document) = self.active_document_mut() {
|
||||
document.rulers_visible = !document.rulers_visible;
|
||||
|
||||
responses.add(DocumentMessage::RenderRulers);
|
||||
responses.add(MenuBarMessage::SendLayout);
|
||||
}
|
||||
}
|
||||
PortfolioMessage::UpdateDocumentWidgets => {
|
||||
if let Some(document) = self.active_document() {
|
||||
document.update_document_widgets(responses);
|
||||
|
|
@ -552,6 +566,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||
OpenDocument,
|
||||
PasteIntoFolder,
|
||||
PrevDocument,
|
||||
ToggleRulers,
|
||||
);
|
||||
|
||||
if self.graph_view_overlay_open {
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
let rulerOrigin: XY = { x: 0, y: 0 };
|
||||
let rulerSpacing = 100;
|
||||
let rulerInterval = 100;
|
||||
let rulersVisible = true;
|
||||
|
||||
// Rendered SVG viewport data
|
||||
let artworkSvg = "";
|
||||
|
|
@ -213,10 +214,11 @@
|
|||
scrollbarMultiplier = multiplier;
|
||||
}
|
||||
|
||||
export function updateDocumentRulers(origin: XY, spacing: number, interval: number) {
|
||||
export function updateDocumentRulers(origin: XY, spacing: number, interval: number, visible: boolean) {
|
||||
rulerOrigin = origin;
|
||||
rulerSpacing = spacing;
|
||||
rulerInterval = interval;
|
||||
rulersVisible = visible;
|
||||
}
|
||||
|
||||
// Update mouse cursor icon
|
||||
|
|
@ -371,8 +373,8 @@
|
|||
editor.subscriptions.subscribeJsMessage(UpdateDocumentRulers, async (data) => {
|
||||
await tick();
|
||||
|
||||
const { origin, spacing, interval } = data;
|
||||
updateDocumentRulers(origin, spacing, interval);
|
||||
const { origin, spacing, interval, visible } = data;
|
||||
updateDocumentRulers(origin, spacing, interval, visible);
|
||||
});
|
||||
|
||||
// Update mouse cursor icon
|
||||
|
|
@ -440,13 +442,17 @@
|
|||
</LayoutCol>
|
||||
</LayoutCol>
|
||||
<LayoutCol class="table">
|
||||
<LayoutRow class="ruler-or-scrollbar top-ruler">
|
||||
<RulerInput origin={rulerOrigin.x} majorMarkSpacing={rulerSpacing} numberInterval={rulerInterval} direction="Horizontal" bind:this={rulerHorizontal} />
|
||||
</LayoutRow>
|
||||
{#if rulersVisible}
|
||||
<LayoutRow class="ruler-or-scrollbar top-ruler">
|
||||
<RulerInput origin={rulerOrigin.x} majorMarkSpacing={rulerSpacing} numberInterval={rulerInterval} direction="Horizontal" bind:this={rulerHorizontal} />
|
||||
</LayoutRow>
|
||||
{/if}
|
||||
<LayoutRow class="viewport-container">
|
||||
<LayoutCol class="ruler-or-scrollbar">
|
||||
<RulerInput origin={rulerOrigin.y} majorMarkSpacing={rulerSpacing} numberInterval={rulerInterval} direction="Vertical" bind:this={rulerVertical} />
|
||||
</LayoutCol>
|
||||
{#if rulersVisible}
|
||||
<LayoutCol class="ruler-or-scrollbar">
|
||||
<RulerInput origin={rulerOrigin.y} majorMarkSpacing={rulerSpacing} numberInterval={rulerInterval} direction="Vertical" bind:this={rulerVertical} />
|
||||
</LayoutCol>
|
||||
{/if}
|
||||
<LayoutCol class="viewport-container" styles={{ cursor: canvasCursor }}>
|
||||
{#if cursorEyedropper}
|
||||
<EyedropperPreview
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
|
||||
const RULER_THICKNESS = 16;
|
||||
const MAJOR_MARK_THICKNESS = 16;
|
||||
const MEDIUM_MARK_THICKNESS = 6;
|
||||
|
|
@ -96,6 +98,8 @@
|
|||
const remainder = n % m;
|
||||
return Math.floor(remainder >= 0 ? remainder : remainder + m);
|
||||
}
|
||||
|
||||
onMount(resize);
|
||||
</script>
|
||||
|
||||
<div class={`ruler-input ${direction.toLowerCase()}`} bind:this={rulerInput}>
|
||||
|
|
|
|||
|
|
@ -473,6 +473,8 @@ export class UpdateDocumentRulers extends JsMessage {
|
|||
readonly spacing!: number;
|
||||
|
||||
readonly interval!: number;
|
||||
|
||||
readonly visible!: boolean;
|
||||
}
|
||||
|
||||
export class UpdateEyedropperSamplingState extends JsMessage {
|
||||
|
|
|
|||
Loading…
Reference in New Issue