| ... | @@ -20,7 +20,7 @@ pub(crate) const PAD: f32 = 4.0; | ... | @@ -20,7 +20,7 @@ pub(crate) const PAD: f32 = 4.0; |
| 20 | /// A palette's rows and filter field, and Snowbound's more compact menu rows. | 20 | /// A palette's rows and filter field, and Snowbound's more compact menu rows. |
| 21 | const ROW: f32 = 26.0; | 21 | const ROW: f32 = 26.0; |
| 22 | pub(crate) const MENU_ROW: f32 = 22.0; | 22 | pub(crate) const MENU_ROW: f32 = 22.0; |
| 23 | /// Rows a list shows before it scrolls. | 23 | /// Rows a palette or a dialog's list shows before it scrolls; a menu runs to the window's edge. |
| 24 | const ROWS: f32 = 12.0; | 24 | const ROWS: f32 = 12.0; |
| 25 | /// How long the pointer rests on a row before its submenu opens, as Windows waits by default. | 25 | /// How long the pointer rests on a row before its submenu opens, as Windows waits by default. |
| 26 | const SUBMENU_DELAY: Duration = Duration::from_millis(200); | 26 | const SUBMENU_DELAY: Duration = Duration::from_millis(200); |
| ... | @@ -115,6 +115,12 @@ pub fn menu( | ... | @@ -115,6 +115,12 @@ pub fn menu( |
| 115 | .map_or(0.0, |badge| crate::badge_width(ui, badge) + ICON_GAP) | 115 | .map_or(0.0, |badge| crate::badge_width(ui, badge) + ICON_GAP) |
| 116 | }) | 116 | }) |
| 117 | .collect(); | 117 | .collect(); |
| | 118 | let window = ui.rect(Id::ROOT).map_or(0.0, |window| window[3]); |
| | 119 | let field = if filter.is_some() { |
| | 120 | ROW + style.pad |
| | 121 | } else { |
| | 122 | 0.0 |
| | 123 | }; |
| 118 | let mut measure = |text| ui.texts.label(text, style.font_size, ui.frame).size[0]; | 124 | let mut measure = |text| ui.texts.label(text, style.font_size, ui.frame).size[0]; |
| 119 | let [text, shortcut] = | 125 | let [text, shortcut] = |
| 120 | items | 126 | items |
| ... | @@ -140,7 +146,7 @@ pub fn menu( | ... | @@ -140,7 +146,7 @@ pub fn menu( |
| 140 | } else { | 146 | } else { |
| 141 | 0.0 | 147 | 0.0 |
| 142 | } + if icons(items) { ICON + ICON_GAP } else { 0.0 } | 148 | } + if icons(items) { ICON + ICON_GAP } else { 0.0 } |
| 143 | + if items.len() as f32 > ROWS { | 149 | + if items.len() as f32 * style.row > window - 4.0 * PAD - field { |
| 144 | GUTTER | 150 | GUTTER |
| 145 | } else { | 151 | } else { |
| 146 | 0.0 | 152 | 0.0 |
| ... | @@ -510,9 +516,13 @@ fn choose( | ... | @@ -510,9 +516,13 @@ fn choose( |
| 510 | 0.0 | 516 | 0.0 |
| 511 | }; | 517 | }; |
| 512 | let content = matches.count() as f32 * row + matches.space_before(matches.count()); | 518 | let content = matches.count() as f32 * row + matches.space_before(matches.count()); |
| 513 | let view = content | 519 | let room = window - 4.0 * PAD - field; |
| 514 | .max(row) | 520 | let most = if role == Role::Menu { |
| 515 | .min((ROWS * row).min(window - 4.0 * PAD - field).max(row)); | 521 | room |
| | 522 | } else { |
| | 523 | (ROWS * row).min(room) |
| | 524 | }; |
| | 525 | let view = content.max(row).min(most.max(row)); |
| 516 | let chosen = if matches.count() == 0 { | 526 | let chosen = if matches.count() == 0 { |
| 517 | ui.leaf( | 527 | ui.leaf( |
| 518 | "empty", | 528 | "empty", |