mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-15 01:15:25 +00:00
Contextual Task Bar: a bar without its font controls leaves their wheel
On a canvas too narrow for the font controls, the bar still shows but leaves them out, and Window > Contextual Task Bar can hide the bar. In both cases the font family field the bar drew before no longer takes the mouse wheel, so the turn scrolls the canvas.
This commit is contained in:
@@ -70,7 +70,7 @@ pub use selection_marks::SelectionMarks;
|
||||
#[cfg(test)]
|
||||
pub(crate) use task_bar::chip_paints;
|
||||
use task_bar::task_bar;
|
||||
pub(crate) use task_bar::{has_colors, task_bar_rect, task_bar_shows_type};
|
||||
pub(crate) use task_bar::{has_colors, task_bar_rect, task_bar_shows_fonts, task_bar_shows_type};
|
||||
#[cfg(test)]
|
||||
use tool_overlays::{DIAL_RADIUS, HiddenMarks};
|
||||
pub use tool_overlays::{HiddenChars, SpellingMarks};
|
||||
|
||||
@@ -13,6 +13,12 @@ pub(crate) fn task_bar_rect(ctx: &egui::Context) -> Option<egui::Rect> {
|
||||
ctx.memory(|m| m.areas().is_visible(&egui::LayerId::new(egui::Order::Middle, id)).then(|| m.area_rect(id)).flatten())
|
||||
}
|
||||
|
||||
/// Whether the Contextual Task Bar, where it was last drawn, held the font controls: on a canvas
|
||||
/// too narrow for them it leaves them out.
|
||||
pub(crate) fn task_bar_shows_fonts(ctx: &egui::Context) -> bool {
|
||||
task_bar_rect(ctx).is_some() && ctx.data(|d| d.get_temp::<bool>(task_bar_id().with("fonts")).unwrap_or(false))
|
||||
}
|
||||
|
||||
/// Whether the objects `ids` (or anything inside them) are painted with a colour: a solid colour,
|
||||
/// a gradient's stops or a mesh's points, which Recolor Artwork can change.
|
||||
pub(crate) fn has_colors(doc: &vectorcraft_doc::Document, ids: &[vectorcraft_doc::NodeId]) -> bool {
|
||||
@@ -235,6 +241,7 @@ pub(super) fn task_bar(app: &mut VectorcraftApp, ui: &mut Ui, xf: &Xf) {
|
||||
let bounds = xf.rect.shrink(8.0);
|
||||
// On a canvas too narrow for the type controls at their narrowest, the bar leaves them out.
|
||||
let fonts = fonts && bounds.width() - 18.0 >= crate::panels::character::task_bar_min_room();
|
||||
ui.ctx().data_mut(|d| d.insert_temp(task_bar_id().with("fonts"), fonts));
|
||||
// The width of the bar's frame (margins and stroke), its handle, Fill and Stroke chips,
|
||||
// Recolor Artwork, Lock or Shape Properties, and More Options, each after a 6-point gap.
|
||||
let chips: f32 =
|
||||
|
||||
@@ -70,7 +70,12 @@ impl WheelOwner {
|
||||
Self::ControlPopover(anchor) => {
|
||||
return app.ui.control_bar && app.ui.screen_mode < 2 && widgets::popover_is_open(ctx, anchor);
|
||||
}
|
||||
Self::TaskBar => return crate::canvas::task_bar_shows_type(app) && crate::canvas::task_bar_rect(ctx).is_some(),
|
||||
Self::TaskBar => {
|
||||
return app.ui.task_bar
|
||||
&& app.ui.screen_mode < 3
|
||||
&& crate::canvas::task_bar_shows_type(app)
|
||||
&& crate::canvas::task_bar_shows_fonts(ctx);
|
||||
}
|
||||
Self::Character => "character",
|
||||
Self::Properties => {
|
||||
let selected = app.session.active().and_then(|document| document.selection.objects.first().and_then(|id| document.doc.node(*id)));
|
||||
|
||||
@@ -769,6 +769,47 @@ fn selected_types_font_controls_take_a_second_row_on_a_narrow_canvas() {
|
||||
assert!(canvas.contains_rect(r) && r.height() < 60.0, "no font controls on a 160 px screen: {r:?} in {canvas:?}");
|
||||
}
|
||||
|
||||
/// When the canvas narrows so far that the bar leaves its font controls out, the font family
|
||||
/// field it drew before no longer takes the mouse wheel.
|
||||
#[test]
|
||||
fn a_task_bar_without_its_font_controls_leaves_their_wheel() {
|
||||
let mut app = app();
|
||||
app.run("tool.select", json!({"tool": "type"})).unwrap();
|
||||
app.run("text.create", json!({"x": 20, "y": 60, "text": "Hello", "size": 20})).unwrap();
|
||||
app.session.apply_actions(vec![vectorcraft_tools::Action::Notify("text.editNew".into())]).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
let draw = |app: &mut VectorcraftApp, width: f32| {
|
||||
let screen = Rect::from_min_size(Pos2::ZERO, vec2(width, 700.0));
|
||||
for _ in 0..3 {
|
||||
let mut out = ctx.run_ui(egui::RawInput { screen_rect: Some(screen), ..Default::default() }, |ui| canvas::show(app, ui));
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
};
|
||||
draw(&mut app, 1000.0);
|
||||
let bar = canvas::task_bar_rect(&ctx).expect("the task bar shows");
|
||||
let viewport = egui::ViewportId::ROOT;
|
||||
let points = (0..(bar.width() / 4.0) as usize).flat_map(|x| (0..(bar.height() / 4.0) as usize).map(move |y| (x, y)));
|
||||
let field = points
|
||||
.map(|(x, y)| bar.min + vec2(x as f32 * 4.0, y as f32 * 4.0))
|
||||
.find(|p| crate::font_menu::wheel_field_layer_for_test(&ctx, viewport, *p).is_some())
|
||||
.expect("the bar's font family field takes the wheel");
|
||||
draw(&mut app, 160.0);
|
||||
assert!(canvas::task_bar_rect(&ctx).is_some(), "the bar still shows, without its font controls");
|
||||
crate::font_menu::sync_wheel_target(&app, &ctx, viewport);
|
||||
assert!(crate::font_menu::wheel_field_layer_for_test(&ctx, viewport, field).is_none(), "the left-out field at {field:?} still takes the wheel");
|
||||
|
||||
// Hiding the bar (Window › Contextual Task Bar) releases the field before the next layout.
|
||||
draw(&mut app, 1000.0);
|
||||
assert!(crate::font_menu::wheel_field_layer_for_test(&ctx, viewport, field).is_some(), "the field is back");
|
||||
app.run("window.taskBar", json!({})).unwrap();
|
||||
crate::font_menu::sync_wheel_target(&app, &ctx, viewport);
|
||||
assert!(
|
||||
crate::font_menu::wheel_field_layer_for_test(&ctx, viewport, field).is_none(),
|
||||
"the hidden bar's field at {field:?} still takes the wheel"
|
||||
);
|
||||
}
|
||||
|
||||
/// While a Type tool edits type, the Fill chip shows the selected characters' fill, and "?" where
|
||||
/// their fills differ.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user