Add pin and cut icons; improve menu bar shortcut labels to choose shortest

This commit is contained in:
Keavon Chambers 2025-02-05 18:30:10 -08:00
parent f13efd2d06
commit 0ec91bfe01
8 changed files with 48 additions and 7 deletions

View file

@ -92,11 +92,9 @@ impl InputMapperMessageHandler {
.collect::<Vec<_>>();
// Append the key button for the entry
use InputMapperMessage as IMM;
match entry.input {
InputMapperMessage::KeyDown(key) => keys.push(key),
InputMapperMessage::KeyUp(key) => keys.push(key),
InputMapperMessage::KeyDownNoRepeat(key) => keys.push(key),
InputMapperMessage::KeyUpNoRepeat(key) => keys.push(key),
IMM::KeyDown(key) | IMM::KeyUp(key) | IMM::KeyDownNoRepeat(key) | IMM::KeyUpNoRepeat(key) => keys.push(key),
_ => (),
}

View file

@ -1,4 +1,4 @@
use super::input_keyboard::{all_required_modifiers_pressed, KeysGroup, LayoutKeysGroup};
use super::input_keyboard::{all_required_modifiers_pressed, Key, KeysGroup, LayoutKeysGroup};
use crate::messages::input_mapper::key_mapping::MappingVariant;
use crate::messages::input_mapper::utility_types::input_keyboard::{KeyStates, NUMBER_OF_KEYS};
use crate::messages::input_mapper::utility_types::input_mouse::NUMBER_OF_MOUSE_BUTTONS;
@ -134,7 +134,29 @@ impl ActionKeys {
pub fn to_keys(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) -> String {
match self {
Self::Action(action) => {
if let Some(keys) = action_input_mapping(action).get_mut(0) {
// Take the shortest sequence of keys
let mut key_sequences = action_input_mapping(action);
key_sequences.sort_by_key(|keys| keys.0.len());
let mut secondary_key_sequence = key_sequences.get(1).cloned();
let mut key_sequence = key_sequences.get_mut(0);
// TODO: Replace this exception with a per-action choice of canonical hotkey
if let Some(key_sequence) = &mut key_sequence {
if key_sequence.0.as_slice() == [Key::MouseBack] {
if let Some(replacement) = &mut secondary_key_sequence {
std::mem::swap(*key_sequence, replacement);
}
}
}
if let Some(key_sequence) = &mut key_sequence {
if key_sequence.0.as_slice() == [Key::MouseForward] {
if let Some(replacement) = &mut secondary_key_sequence {
std::mem::swap(*key_sequence, replacement);
}
}
}
if let Some(keys) = key_sequence {
let mut taken_keys = KeysGroup::default();
std::mem::swap(keys, &mut taken_keys);
let description = taken_keys.to_string();

View file

@ -156,6 +156,7 @@ impl LayoutHolder for MenuBarMessageHandler {
vec![
MenuBarEntry {
label: "Cut".into(),
icon: Some("Cut".into()),
shortcut: action_keys!(PortfolioMessageDiscriminant::Cut),
action: MenuBarEntry::create_action(|_| PortfolioMessage::Cut { clipboard: Clipboard::Device }.into()),
disabled: no_active_document || !has_selected_layers,

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path d="M12,9c-.39,0-.65.06-.88.06-.5,0-.89-.26-2.25-1.92L3,0s-1.01.54-.04,2.27c3.12,5.6,3.62,7,4.9,7.19,1.08.16,1.42.82,1.23,1.88-.05.21-.08.44-.08.67,0,1.66,1.34,3,3,3s3-1.34,3-3-1.34-3-3-3ZM8,8.75c-.41,0-.75-.34-.75-.75s.34-.75.75-.75.75.34.75.75-.34.75-.75.75ZM12,13.8c-.99,0-1.8-.81-1.8-1.8s.81-1.8,1.8-1.8,1.8.81,1.8,1.8-.81,1.8-1.8,1.8z" />
<path d="M7.13,9.97c-.48-.22-.89-.62-1.37-1.32-.37.32-.61.41-.88.41-.23,0-.49-.06-.88-.06-1.66,0-3,1.34-3,3s1.34,3,3,3,3-1.34,3-3c0-.23-.03-.45-.08-.67-.11-.58-.05-1.04.21-1.36ZM4,13.8c-.99,0-1.8-.81-1.8-1.8s.81-1.8,1.8-1.8,1.8.81,1.8,1.8-.81,1.8-1.8,1.8z" />
<path d="M13,0s-.01.02-4.55,5.53l.95,1.16c.28.34.52.62.71.84.65-1.09,1.52-2.75,2.92-5.26.97-1.73-.04-2.27-.04-2.27z" />
</svg>

After

Width:  |  Height:  |  Size: 800 B

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<polygon points="4.65 10.65 1.15 14.15 1 15 1.85 14.85 5.35 11.35 4.65 10.65" />
<path d="M15,4.59l-3.59-3.59c-.39-.39-1.02-.39-1.41,0s-.39,1.02,0,1.41l3.59,3.59c.39.39,1.02.39,1.41,0,.39-.39.39-1.02,0-1.41z" />
<path d="M12.5,6.5l-3-3-2.96,2.4c-1.24-.52-2.69-.39-3.82.4l6.97,6.97c.79-1.13.92-2.58.4-3.82l2.4-2.96z" />
</svg>

After

Width:  |  Height:  |  Size: 390 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<polygon points="1.85 14.85 1 15 1.15 14.15 4.65 10.65 5.35 11.35 1.85 14.85" />
<path d="M11.21,1.21l3.6,3.58c-.15-.03-.3-.05-.45-.05-.51,0-.97.19-1.31.53l-2.6,2.68-.44.45.21.59c.26.72,0,1.89-.57,2.84l-5.47-5.47c.69-.41,1.52-.68,2.2-.68.24,0,.46.03.63.1l.59.21.45-.44,2.68-2.62c.44-.43.62-1.06.48-1.72,0,0,0,0,0,0h0M11.21.21c-.26,0-.51.1-.71.29-.24.24-.33.57-.27.88.06.3.01.62-.21.83l-2.68,2.62c-.3-.11-.63-.16-.97-.16-1.3,0-2.82.69-3.71,1.58l7.07,7.07c1.13-1.13,1.93-3.27,1.42-4.68l2.6-2.68c.16-.16.37-.23.59-.23.08,0,.17,0,.25.03.07.01.13.02.2.02.25,0,.5-.09.69-.29.39-.39.39-1.02,0-1.41l-3.59-3.59c-.2-.2-.45-.29-.71-.29h0z" />
</svg>

After

Width:  |  Height:  |  Size: 702 B

View file

@ -28,7 +28,7 @@
<div class="expand-arrow" />
<TextLabel bold={true}>{widgetData.name}</TextLabel>
<IconButton
icon={widgetData.pinned ? "CheckboxChecked" : "CheckboxUnchecked"}
icon={widgetData.pinned ? "PinActive" : "PinInactive"}
tooltip={widgetData.pinned ? "Unpin this node so it's no longer shown here when nothing is selected" : "Pin this node so it's shown here when nothing is selected"}
size={24}
action={(e) => {

View file

@ -109,6 +109,7 @@ import CheckboxUnchecked from "@graphite-frontend/assets/icon-16px-solid/checkbo
import Copy from "@graphite-frontend/assets/icon-16px-solid/copy.svg";
import Credits from "@graphite-frontend/assets/icon-16px-solid/credits.svg";
import CustomColor from "@graphite-frontend/assets/icon-16px-solid/custom-color.svg";
import Cut from "@graphite-frontend/assets/icon-16px-solid/cut.svg";
import Edit from "@graphite-frontend/assets/icon-16px-solid/edit.svg";
import EyeHidden from "@graphite-frontend/assets/icon-16px-solid/eye-hidden.svg";
import EyeHide from "@graphite-frontend/assets/icon-16px-solid/eye-hide.svg";
@ -144,6 +145,8 @@ import Node from "@graphite-frontend/assets/icon-16px-solid/node.svg";
import PadlockLocked from "@graphite-frontend/assets/icon-16px-solid/padlock-locked.svg";
import PadlockUnlocked from "@graphite-frontend/assets/icon-16px-solid/padlock-unlocked.svg";
import Paste from "@graphite-frontend/assets/icon-16px-solid/paste.svg";
import PinActive from "@graphite-frontend/assets/icon-16px-solid/pin-active.svg";
import PinInactive from "@graphite-frontend/assets/icon-16px-solid/pin-inactive.svg";
import Random from "@graphite-frontend/assets/icon-16px-solid/random.svg";
import Regenerate from "@graphite-frontend/assets/icon-16px-solid/regenerate.svg";
import Reload from "@graphite-frontend/assets/icon-16px-solid/reload.svg";
@ -188,6 +191,7 @@ const SOLID_16PX = {
Copy: { svg: Copy, size: 16 },
Credits: { svg: Credits, size: 16 },
CustomColor: { svg: CustomColor, size: 16 },
Cut: { svg: Cut, size: 16 },
Edit: { svg: Edit, size: 16 },
Eyedropper: { svg: Eyedropper, size: 16 },
EyeHidden: { svg: EyeHidden, size: 16 },
@ -223,6 +227,8 @@ const SOLID_16PX = {
PadlockLocked: { svg: PadlockLocked, size: 16 },
PadlockUnlocked: { svg: PadlockUnlocked, size: 16 },
Paste: { svg: Paste, size: 16 },
PinActive: { svg: PinActive, size: 16 },
PinInactive: { svg: PinInactive, size: 16 },
Random: { svg: Random, size: 16 },
Regenerate: { svg: Regenerate, size: 16 },
Reload: { svg: Reload, size: 16 },