PlatformChrome.FullBleed 추가 - 화면을 꽉 쓰는 모듈이 셸 여백을 끌 수 있게
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
00b3754063
commit
6991dfdfcf
2
dist/README.txt
vendored
2
dist/README.txt
vendored
@ -1,5 +1,5 @@
|
||||
UbisamBase 플랫폼 배포 폴더 (빌드할 때 자동 생성 - 직접 고치지 마세요)
|
||||
갱신 시각 : 2026-09-21 22:42:14
|
||||
갱신 시각 : 2026-09-21 22:44:28
|
||||
빌드 구성 : Release
|
||||
원본 소스 : D:\업무\03_개발\Source\용접기\08_UbisamPlatform\
|
||||
----
|
||||
|
||||
BIN
dist/UbisamBase.Core.dll
vendored
BIN
dist/UbisamBase.Core.dll
vendored
Binary file not shown.
BIN
dist/UbisamBase.Launcher.exe
vendored
BIN
dist/UbisamBase.Launcher.exe
vendored
Binary file not shown.
BIN
dist/UbisamBase.Shell.exe
vendored
BIN
dist/UbisamBase.Shell.exe
vendored
Binary file not shown.
2
dist/platform-version.json
vendored
2
dist/platform-version.json
vendored
@ -1,4 +1,4 @@
|
||||
{
|
||||
"version": "2026-09-21 22:42:14",
|
||||
"version": "2026-09-21 22:44:28",
|
||||
"configuration": "Release"
|
||||
}
|
||||
|
||||
@ -19,3 +19,4 @@
|
||||
| 2026-09-21 | 업데이트 진행 창 추가 — 런처를 누르자마자 확인/받기 상태와 진행률을 보여주고, 다 받은 뒤 설치 여부를 묻는다 |
|
||||
| 2026-09-21 | Shell.exe를 직접 실행하면 런처로 넘기도록 — 진입점을 런처 하나로 통일(업데이트 확인 누락 방지) |
|
||||
| 2026-09-21 | 런처 창(진행·업데이트 안내)이 앱의 테마 설정(다크/라이트)을 따르도록 — 윈도우 설정만 보던 것을 수정 |
|
||||
| 2026-09-21 | `PlatformChrome.FullBleed` 첨부 속성 추가 — 화면을 꽉 쓰는 모듈이 셸 여백을 끌 수 있게 (건의 6) |
|
||||
|
||||
@ -485,6 +485,26 @@ public partial class DeckViewModel : ObservableObject, ICloseGuard
|
||||
이 확인을 건너뛴다 — 모듈에서는 쓰지 말 것.
|
||||
- UI 설정의 "상단 바 접기"는 사용자가 저장해 두는 별개 취향이다. 둘 중 하나라도 숨기라고 하면 상단 바는 숨는다.
|
||||
|
||||
## 8-4. 화면을 꽉 쓰는 모듈 — `PlatformChrome.FullBleed`
|
||||
|
||||
셸은 모듈 화면 둘레에 여백(26,22)을 준다. 설정 화면이나 폼처럼 글을 읽는 화면에는 그 여백이
|
||||
있어야 보기 좋지만, 편집기·지도·카메라처럼 **자기 안에서 이미 칸을 나누는 모듈**은 여백이 한 겹 더
|
||||
붙으면 화면만 좁아지고 테두리처럼 보인다. 그런 모듈은 View에 첨부 속성 하나만 붙이면 된다.
|
||||
|
||||
```xml
|
||||
<UserControl x:Class="MyModule.Views.EditorView"
|
||||
xmlns:shell="clr-namespace:UbisamBase.Core.Shell;assembly=UbisamBase.Core"
|
||||
shell:PlatformChrome.FullBleed="True">
|
||||
```
|
||||
|
||||
- 기본은 여백 있음(False). 이 화면이 떠 있는 동안만 여백이 사라지고, 다른 탭으로 옮기면 그 탭의
|
||||
설정을 따른다.
|
||||
- 발표자 모드(`PlatformChrome.IsVisible = false`)에서는 이 값과 무관하게 여백이 0이다.
|
||||
- 코드에서 바꿔도 된다 — `PlatformChrome.SetFullBleed(view, true)`. 떠 있는 동안 바꿔도 셸이 다시
|
||||
계산한다(`FullBleedChanged`).
|
||||
- **비주얼 트리를 거슬러 올라가 Border의 Padding을 직접 0으로 만들지 말 것.** 플랫폼 레이아웃이
|
||||
바뀌면 그대로 깨진다 — 이 속성이 그 자리를 대신한다.
|
||||
|
||||
## 9. 테마 · UI 컨벤션
|
||||
|
||||
- `Ubisam.Brush.*`, `Ubisam.Style.*`로 시작하는 리소스가 다크/라이트 테마 전체를 정의
|
||||
|
||||
35
src/UbisamBase.Core/Converters/ContentPaddingConverter.cs
Normal file
35
src/UbisamBase.Core/Converters/ContentPaddingConverter.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using UbisamBase.Core.Shell;
|
||||
|
||||
namespace UbisamBase.Core.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// 셸 컨텐츠 영역의 여백을 정한다. 값 두 개를 받는다 — (1) 플랫폼 껍데기가 보이는지,
|
||||
/// (2) 지금 올라와 있는 모듈 화면.
|
||||
///
|
||||
/// 발표자 모드(껍데기 숨김)이거나 그 화면이 <see cref="PlatformChrome.FullBleedProperty"/>를 켜 뒀으면
|
||||
/// 여백 0, 그 외에는 <see cref="Default"/>.
|
||||
/// </summary>
|
||||
public class ContentPaddingConverter : IMultiValueConverter
|
||||
{
|
||||
/// <summary>평소 여백. ShellStyles.xaml에서 지정한다.</summary>
|
||||
public Thickness Default { get; set; }
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var chromeVisible = values.Length > 0 && values[0] is bool visible && visible;
|
||||
if (!chromeVisible)
|
||||
{
|
||||
return new Thickness(0);
|
||||
}
|
||||
|
||||
var content = values.Length > 1 ? values[1] as DependencyObject : null;
|
||||
return content != null && PlatformChrome.GetFullBleed(content) ? new Thickness(0) : Default;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
=> throw new NotSupportedException();
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
|
||||
namespace UbisamBase.Core.Shell;
|
||||
|
||||
@ -38,6 +39,35 @@ public static class PlatformChrome
|
||||
/// <summary>보임/숨김을 뒤집는다 — 발표 중 단축키나 버튼에 걸어 쓰기 좋다.</summary>
|
||||
public static void Toggle() => IsVisible = !IsVisible;
|
||||
|
||||
/// <summary>
|
||||
/// 모듈 화면에 붙이는 첨부 속성. True면 셸이 그 화면 둘레의 여백(26,22)을 주지 않는다.
|
||||
///
|
||||
/// 편집기·지도·카메라처럼 화면을 꽉 쓰는 모듈은 자기 안에서 이미 칸을 나누고 각 칸이 자기 여백을
|
||||
/// 갖는다. 거기에 바깥 여백이 한 겹 더 붙으면 화면만 좁아지고 테두리처럼 보인다. 반대로 설정
|
||||
/// 화면이나 폼은 여백이 있어야 읽기 좋으므로, 기본은 여백 있음이고 필요한 모듈만 끈다.
|
||||
///
|
||||
/// <code><UserControl ... shell:PlatformChrome.FullBleed="True"></code>
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty FullBleedProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"FullBleed",
|
||||
typeof(bool),
|
||||
typeof(PlatformChrome),
|
||||
new PropertyMetadata(false, OnFullBleedChanged));
|
||||
|
||||
public static void SetFullBleed(DependencyObject element, bool value)
|
||||
=> element.SetValue(FullBleedProperty, value);
|
||||
|
||||
public static bool GetFullBleed(DependencyObject element)
|
||||
=> element != null && (bool)element.GetValue(FullBleedProperty);
|
||||
|
||||
/// <summary>화면이 떠 있는 동안 값을 바꿔도 셸이 여백을 다시 계산하도록 알린다
|
||||
/// (첨부 속성은 셸의 바인딩에서 직접 감시할 수 없다).</summary>
|
||||
public static event EventHandler? FullBleedChanged;
|
||||
|
||||
private static void OnFullBleedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
=> FullBleedChanged?.Invoke(d, EventArgs.Empty);
|
||||
|
||||
/// <summary>보임/숨김이 바뀔 때마다 새 값(true=보임)과 함께 알린다. 모듈이 자기가 바꾸지 않은
|
||||
/// 변화(설정의 "상단 바 접기", 다른 모듈, 단축키)에도 반응할 수 있게 하는 통로다 —
|
||||
/// 발표 모드를 나갈 때 타이머를 멈추거나 띄워둔 창을 닫는 정리에 쓴다.
|
||||
|
||||
@ -161,8 +161,14 @@
|
||||
|
||||
<!-- 모듈이 마운트되기 전에는 사선 해치가 빈 슬롯을 표시, 마운트되면 단색 배경.
|
||||
여백은 발표자 모드에서 0이 된다 — 껍데기를 걷었는데 액자처럼 테두리가 남으면 안 된다. -->
|
||||
<Border Grid.Row="0"
|
||||
Padding="{Binding Path=(shell:PlatformChrome.IsVisible), Converter={StaticResource BoolToContentPadding}}">
|
||||
<Border x:Name="ContentBorder" Grid.Row="0">
|
||||
<Border.Padding>
|
||||
<!-- 발표자 모드이거나, 올라온 모듈 화면이 FullBleed면 여백 0. -->
|
||||
<MultiBinding Converter="{StaticResource ContentPadding}">
|
||||
<Binding Path="(shell:PlatformChrome.IsVisible)"/>
|
||||
<Binding Path="SelectedMainTab.CurrentContent"/>
|
||||
</MultiBinding>
|
||||
</Border.Padding>
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="{DynamicResource Ubisam.Brush.ContentBackground}"/>
|
||||
|
||||
@ -38,6 +38,10 @@ public partial class ShellWindow : Window
|
||||
DataContext = viewModel;
|
||||
|
||||
viewModel.UiSettings.PropertyChanged += OnUiSettingsChanged;
|
||||
|
||||
// FullBleed는 첨부 속성이라 바인딩이 스스로 변화를 못 본다 — 바뀌면 여백을 다시 계산한다.
|
||||
PlatformChrome.FullBleedChanged += OnFullBleedChanged;
|
||||
Closed += (_, _) => PlatformChrome.FullBleedChanged -= OnFullBleedChanged;
|
||||
ApplyNavPosition(viewModel.UiSettings.NavPosition);
|
||||
ApplyToastPosition(viewModel.UiSettings.ToastPosition);
|
||||
|
||||
@ -313,6 +317,9 @@ public partial class ShellWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFullBleedChanged(object? sender, EventArgs e)
|
||||
=> BindingOperations.GetMultiBindingExpression(ContentBorder, Border.PaddingProperty)?.UpdateTarget();
|
||||
|
||||
private void OnUiSettingsChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(UiSettingsService.NavPosition))
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
<conv:AllBoolToVisibilityConverter x:Key="AllBoolToVis"/>
|
||||
<!-- 발표자 모드(PlatformChrome.IsVisible=false)에서는 컨텐츠 여백을 없애 화면을 꽉 채운다. -->
|
||||
<conv:BoolToThicknessConverter x:Key="BoolToContentPadding" True="26,22" False="0"/>
|
||||
<!-- 컨텐츠 여백 — 발표자 모드이거나 그 화면이 FullBleed면 0. -->
|
||||
<conv:ContentPaddingConverter x:Key="ContentPadding" Default="26,22"/>
|
||||
<conv:InverseBooleanConverter x:Key="InverseBool"/>
|
||||
<conv:FirstCharacterConverter x:Key="FirstCharConverter"/>
|
||||
<conv:ToastTypeToBrushConverter x:Key="ToastTypeToBrush"/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user