MewUI - Native AOT 지향 크로스플랫폼 경량 GUI 프레임워크

.NET Windows Linux macOS NativeAOT License: MIT NuGet NuGet Downloads


:grinning_cat: MewUI크로스플랫폼 NativeAOT + Trim 앱을 목표로 하는, 코드 기반(code-first) 경량 .NET GUI 프레임워크입니다.

:test_tube: 실험적 프로토타입

:warning:본 프로젝트는 개념 검증(Proof-of-Concept) 을 위한 실험적 프로토타입입니다.
:warning: v1.0에 도달하는 과정에서 API, 내부 구조, 동작 방식이 크게 변경될 수 있습니다.
:warning: 현재 단계에서는 하위 호환성을 보장하지 않습니다.

:robot: AI 기반 개발 방식

본 프로젝트는 AI 프롬프팅 중심의 개발 방식으로 구현되었습니다.
직접적인 코드 수정 없이 프롬프트 이터레이션을 통해 설계와 구현을 반복하였으며,
각 단계는 개발자가 검토하고 조정하는 방식으로 진행되었습니다.


:rocket: 빠르게 실행해 보기

다음 명령어를 Windows 명령 프롬프트 또는 Linux 및 macOS 터미널에서 입력하면 리포지토리 다운로드나 클론 없이 MewUI를 즉시 실행할 수 있습니다. (.NET 10 SDK가 필요합니다.)

curl -sL https://raw.githubusercontent.com/aprillz/MewUI/refs/heads/main/samples/FBASample/fba_gallery.cs -o - | dotnet run -

이 명령은 GitHub에서 코드를 직접 다운로드하여 실행합니다.

비디오

스크린샷


:sparkles: 주요 특징

  • :package: NativeAOT + Trim 우선
  • :feather: 빠르고 가볍게 (가벼운 실행 파일 크기, 낮은 메모리 풋프린트, 빠른 시작)
  • :puzzle_piece: Fluent C# 마크업

:bullseye: 컨셉

MewUI는 아래 4가지를 최우선으로 둔 code-first UI 라이브러리

  • NativeAOT + Trim 친화
  • 작은 크기, 빠른 시작시간, 적은 메모리 사용
  • XAML 없이 Fluent한 C# 마크업으로 UI 트리 구성
  • AOT 친화적 바인딩

지향하지 않는 것

  • WPF처럼 애니메이션, 화려한 이펙트, 무거운 컴포지션 파이프라인
  • “다 들어있는” 리치 컨트롤 카탈로그
  • 복잡한 경로 기반 데이터 바인딩
  • XAML/WPF 완전 호환이나 디자이너 중심 워크플로우

:test_tube: C# 마크업 예시

  • 샘플 소스: MewUI/samples/MewUI.Sample/Program.cs at main · aprillz/MewUI · GitHub
    var window = new Window()
        .Title("Hello MewUI")
        .Size(520, 360)
        .Padding(12)
        .Content(
            new StackPanel()
                .Spacing(8)
                .Children(
                    new Label()
                        .Text("Hello, Aprillz.MewUI")
                        .FontSize(18)
                        .Bold(),
                    new Button()
                        .Content("Quit")
                        .OnClick(() => Application.Quit())
                )
        );
    
    Application.Run(window);
    

참고 (Aprillz.MewUI.Gallery.exe @v0.10.0)

  • win-x64: ~3,545 KB
  • osx-arm64: ~2,664 KB
  • linux-arm64: ~3,939 KB
7 Likes

v0.15.0

변경 사항

이번 v0.15.0 릴리즈에서는 Calendar/DatePicker 및 PasswordBox 컨트롤 추가, 네이티브 프레임을 지원하는 커스텀 윈도우 크롬, 크로스 플랫폼 윈도우 상태 관리, 가상화 WrapItemsPresenter, 그리고 스타일·속성 값·Grid 레이아웃 시스템의 대규모 리팩터링이 이루어졌습니다.

호환성이 깨지는 변경 사항

  • StyleScope 제거, StyleSheet 기반 스타일 해석으로 통합. Application.StyleSheet을 글로벌 폴백으로 사용
  • PresenterMode 열거형 제거, 프레젠터 확장 메서드를 직접 사용 (예: .StackPresenter(), .WrapPresenter(itemWidth, itemHeight), .FixedHeightPresenter(), .VariableHeightPresenter())

추가됨

  • CalendarDatePicker 컨트롤. 키보드/마우스 내비게이션, 월/년/10년 단위 선택 지원
  • 보안 마스크 텍스트 입력을 위한 PasswordBox 컨트롤

    참고: Password 속성은 평문 문자열로 저장됩니다. 사용 후 직접 클리어하세요 (예: passwordBox.Password = string.Empty;).

  • 크로스 플랫폼 윈도우 상태 지원: Win32, macOS, X11에서 최소화, 최대화, 복원, 최상위, 작업 표시줄 제어
  • 네이티브 크롬을 활용한 커스텀 타이틀 바 — 클라이언트 영역을 타이틀 바로 확장하면서 OS 기능(둥근 모서리, 시스템 버튼) 유지 (#81)
  • 대규모 아이템 컬렉션을 효율적으로 렌더링하는 가상화 WrapItemsPresenter (#94)
  • MewProperty에 속성 값 강제(coercion) 지원 추가
  • MewObject 간 타입 변환 속성-속성 바인딩
  • 공통 네임드 버튼 스타일을 위한 BuiltInStylesStyleSheet 플루언트 정의 API
  • 텍스트 에디터에서 더블 클릭 단어 선택
  • TextBaseMaxLength 속성 추가
  • 취소 가능한 윈도우 닫기를 위한 OnClosing 확장 메서드
  • MenuBarDrawBottomSeparator 속성
  • KeyBinding 생성자에 canExecute 옵션 파라미터
  • GridShowGridLine 속성 추가 (시각적 디버깅용)

개선됨

  • Grid 레이아웃 리팩터링: Auto/Pixel/Star 크기 조정 및 span 처리 개선 (#89)
  • 스타일 해석 및 트리거 애니메이션 로직 리팩터링으로 올바른 속성 소스 추적 및 우선순위 처리
  • Border 렌더링을 배경과 테두리로 분리하여 정확성 향상
  • 테마 및 DPI 알림을 Control뿐만 아니라 모든 FrameworkElement로 확대 (#90)
  • SIMD를 활용한 BGRA 알파 수정 최적화 및 텍스트 알파 힌팅 개선
  • Direct2D DC 렌더 타겟 캐싱으로 비트맵 재사용 및 성능 향상
  • GDI 픽셀별 알파 렌더링 개선 (ClearType 힌팅, 감마 보정)
  • Direct2D 텍스트에 ClearType 안티앨리어싱 항상 적용
  • 포커스 변경 시 IME 조합 취소 및 캐럿 렌더링 개선 (#80)
  • 윈도우 확장 메서드를 Window 하위 클래스에 대해 제네릭으로 변경
  • 액세스 키 밑줄을 텍스트 베이스라인 바로 아래에 렌더링
  • 윈도우 크롬 글리프 추가 및 픽셀 스냅핑 개선
  • 팝업 닫기 시 포커스 및 비주얼 상태 처리 개선

수정됨

  • FindVisualRoot가 실제 비주얼 루트만 반환하도록 수정 (#83)
4 Likes

해커뉴스에 올라왔던 Windows 네이티브 앱 개발이 엉망인 이유 를 작성한 계기가 된 domenic의 WinUI 프로젝트 display-blackout을 MewUI로 포팅해봤습니다.

먼저 링크된 글의 핵심은 이렇습니다.

Domenic Denicola의 글은 Windows 네이티브 앱 개발 환경이 지나치게 복잡하고 단절적이라고 비판합니다. 글에서는 Display Blackout이라는 작은 유틸리티를 예로 들며, 모니터 열거, 비활성 검은 오버레이 창, 글로벌 단축키, 시작 프로그램 등록, 설정 저장, 트레이 아이콘 같은 비교적 단순한 기능조차 최신 Windows App SDK/WinUI 3만으로는 매끄럽게 해결되지 않고, 상당 부분이 여전히 Win32 P/Invoke에 의존한다고 지적합니다. 또한 .NET 10은 기본 탑재되지 않아 framework-dependent 배포의 사용자 경험이 좋지 않고, NativeAOT를 써도 결과물이 작지 않으며, MSIX와 코드 서명 비용 문제도 배포 장벽으로 작용한다고 설명합니다.


DisplayBlackout.MewUI

필요할 때 선택한 디스플레이를 검게 가릴 수 있는 Windows 시스템 트레이 유틸리티입니다. 게임 중 주의 분산을 줄이거나, 하나의 모니터에만 집중하거나, 화상 통화 중 보조 디스플레이를 어둡게 하는 용도에 유용합니다.

원본 프로젝트의 README는 작은 네이티브 Windows 유틸리티를 배포할 때의 현실적인 문제들, 즉 런타임 번들링과 Native AOT 이후에도 남는 외부 런타임 의존성에 대한 우려를 제기합니다. 이 포트는 그와 같은 질문들에 대해 MewUI가 어떤 답을 제시할 수 있는지를 살펴보기 위한 시도입니다.

이 프로젝트는 MewUI 프레임워크 검증을 위한 실험적 포트입니다. 원본 프로젝트를 대체할 목적은 아닙니다.

기능

  • 선택적 블랙아웃: 시각적 모니터 선택기를 통해 검게 가릴 디스플레이를 선택할 수 있습니다.
  • 조절 가능한 불투명도: 블랙아웃 오버레이의 어두운 정도를 조절할 수 있습니다.
  • 클릭 스루 모드: 블랙아웃을 해제하지 않고도 검게 가려진 디스플레이와 상호작용할 수 있습니다.
  • 전역 단축키: Win+Shift+B로 블랙아웃을 전환할 수 있습니다.
  • 시스템 트레이 통합: 알림 영역에서 빠르게 접근할 수 있습니다.
  • 테마 및 강조색 사용자 지정: 라이트/다크/시스템 테마와 여러 강조색을 지원합니다.

요구 사항

  • .NET 10 SDK
  • Windows 7 이상

개인정보 및 보안

이 앱은 관리자 권한 상승이 필요하지 않으며, 네트워크 요청을 보내지 않고, 텔레메트리나 사용자 데이터를 수집하지 않습니다. 설정은 %LocalAppData%/DisplayBlackout/ 아래의 JSON 파일에 로컬로 저장됩니다.

왜 MewUI인가?

원본 작성자는 WinUI 3가 Native AOT를 지원하며, 이를 통해 .NET 런타임을 바이너리에 포함할 수 있다고 언급했습니다. 그러나 WinAppSDK 런타임 자체는 여전히 사용자 시스템에 별도로 설치되어 있어야 합니다. 즉, 반쪽짜리 Native AOT인것이죠.

MewUI는 WinAppSDK 의존성과 외부 런타임 요구사항 없이 배포 및 구동 가능합니다.

출처

이 프로젝트는 다음을 기반으로 합니다.

7 Likes

0.16.0 릴리즈

약 2개월 만에 공개하는 이번 릴리즈는 MewUI의 렌더링 기반과 확장 기능을 크게 정비한 버전입니다.

새로운 IRenderSurface / IRenderDevice 모델을 중심으로 GPU 가속 렌더링 및 외부 GPU 리소스 연동 구조를 재설계했으며, MewUI.Skia, FFmpeg 비디오 재생 샘플, GPU 이미지 필터 그래프를 추가했습니다.

주요 기능으로는 크로스 플랫폼 및 창 간 드래그 앤 드롭, MewUI.MewDock 도킹 프레임워크, ColorPicker, 가변 높이 GridView 가상화, 비트맵 렌더 캐시, 계층적 성능 프로파일러가 포함됩니다.

비트맵 렌더 캐시를 통해 정적인 UI 서브트리의 반복 렌더링 비용을 크게 줄였으며, Direct2D의 특정 화면에서는 약 5,000 FPS까지 렌더링하며 라즈베리파이 4 WSVGA(1024x600) 환경에서도 100프레임 이상을 유지합니다.

또한 Fluent 스타일 메서드 체인을 일관된 형식으로 정렬하는 포매터를 핵심 기능으로 하는 MewUI.Analyzers를 추가했습니다.


변경 사항

이번 릴리즈는 MewUI에 새로운 GPU 가속 렌더링 / 인터롭 기반을 도입합니다.
기존 오프스크린 렌더 타깃 추상화를 새로운 IRenderSurface / IRenderDevice 모델로 대체하고, 외부 GPU / 래스터 인터롭 경로를 추가하며, GPU 가속 이미지 필터 그래프를 도입합니다.

이 기반의 가장 가시적인 결과물은 새 MewUI.Skia 통합과 FFmpeg 기반 비디오 재생 샘플입니다.

이 기반 위에 ColorPicker 컨트롤과 실시간 계층적 성능 프로파일러 등 여러 사용자용 기능이 추가되었습니다.
또한 비동기 OpenGL PBO 업로드, Win32 DirectComposition 기반 투명 창, Direct2D 소비자 간 D3D11 디바이스 공유, GDI 외부 DIB의 1:1 BitBlt 패스 등 굵직한 백엔드 개선도 포함됩니다.

백엔드 인터페이스 및 플랫폼 서피스 네임스페이스 전반에 호환되지 않는 변경이 포함되어 있으므로, 커스텀 백엔드, WriteableBitmapControl, 또는 플랫폼 서피스 인터페이스를 사용하는 코드는 마이그레이션이 필요합니다.

추가됨

라이브러리 / 샘플

  • MewUI.Skia 라이브러리 — GPU 인터롭 경로를 활용한 Skia 통합. Skia(SKCanvas) 기반 콘텐츠를 MewUI 컨트롤 트리 안에서 zero-copy로 합성. Direct2D / GDI / MewVG.Win32 / MewVG.X11 / MewVG.MacOS 백엔드별 interop 브리지 및 메타패키지 포함 (SkiaSharp 3.x 기반).
    MewUI Skia 샘플
  • MewUI.MewDock 도킹 프레임워크 — 탭 / 스플릿 도킹 시스템과 함께 동작하는 샘플 포함.
    MewUI MewDock 샘플
  • MewUI.Analyzers — Fluent 스타일 메서드 체인을 일관된 형식으로 정렬하는 포매터 제공.
    MewUI Analyzers
  • MewUI.Test — 바인딩 / 이벤트 / GDI 백엔드 전반에 대한 테스트 스위트.
  • Skia 샘플 앱 (#116)MewUI.Skia.Sample. 백엔드 토글로 GPU / CPU 폴백 경로 비교.
  • FFmpeg 기반 비디오 재생 샘플MewUI.Video.Sample. NVDEC 하드웨어 디코딩 폴백 포함, 외부 GPU 인터롭 경로를 통해 디코더 프레임을 복사 없이 표시.
  • OffscreenControl 및 커스텀 렌더링 샘플 (#153) — 서브트리를 오프스크린 서피스에 캐시하고 호스트 컨트롤이 단일 이미지로 그리는 방식.

렌더링 / 백엔드

  • 이미지 필터 그래프ImageFilter 노드 그래프와 IImageFilterContext / ScratchSurfacePool 기반 평가 파이프라인. CPU 참조 구현과 Direct2D / Metal / OpenGL GPU 구현을 함께 제공하며, 분리형 가우시안 블러를 기본 노드로 포함.
  • 외부 GPU / 래스터 인터롭IRasterSource, ExternalRasterSource, ExternalGpuWriteScope, GpuInteropInvalidation, GpuResourceAffinity로 외부 또는 GPU 상주 텍스처를 복사 없이 IImage로 노출하고, 공유 GPU 리소스의 쓰기 스코프와 무효화를 관리. Win32에서는 WGL_NV_DX_interop을 통해 D3D11 서피스를 OpenGL 컨텍스트와 공유.
  • Direct2D D3D11 디바이스 공유D3D11RenderTargetDeviceProvider로 여러 D2D 소비자(GPU 서피스 / DXGI 이미지 등)가 단일 D3D11 디바이스를 공유. 디바이스 중복 생성과 컨텍스트 전환 비용 제거.
  • GDI 외부 DIB 이미지 + 1:1 BitBlt 패스 — 외부 DIB를 중간 복사 없이 IImage로 래핑하고, 소스/대상 사각형이 일치하면 StretchBlt 대신 BitBlt로 직접 전송해 픽셀 정확도와 비용 모두 개선.
  • OpenGL 비동기 PBO 업로드 — 픽셀 버퍼 오브젝트와 fence sync 기반 업로더 풀로 프레임당 텍스처 업로드 스톨 제거.
  • IGraphicsContext 확장SetClipPath(PathGeometry), GetClipBoundsLocal() 추가.
  • IImageBrush + TileMode — 이미지 / 패턴 채우기 브러시.
  • PathGeometry.Transform(Matrix3x2) — 변환 행렬을 지오메트리에 미리 베이크해, 이후 Stroke가 element-DIP 두께를 유지하도록 지원.
  • IGlyphOutlineFont — 모든 폰트 백엔드에서 글리프 외곽선을 PathGeometry로 추출. 합성 굵게 / 기울임 지원 포함.
  • 비트맵 리소스의 HasAlpha 플래그 추가 — 알파가 없는 소스에서 GPU 블렌딩 비용 절감.
  • IPixelBufferSource.IsStreaming 플래그 추가 — 자주 갱신되는 픽셀 버퍼임을 명시적으로 선언. MewVG의 비동기 PBO 업로드가 크기 휴리스틱 대신 이 힌트로 분기.
  • SIMD 최적화 RGBA↔BGRA 채널 swap — AVX2 / SSSE3 경로의 32bpp R/B swap. in-place 지원.
  • ImageSource.FromBgraPixels, PixelFormatConverter.FromRgba — raw 픽셀 입력 / non-BGRA 입력을 위한 헬퍼.

플랫폼

  • Win32 투명 창 모드 추상화IWin32TransparencyCapabilities로 layered HWND / DirectComposition / 불투명 중 백엔드가 지원하는 방식을 노출. DCompositionCreateDevice 등 DirectComposition 네이티브 바인딩 포함.
  • 고해상도 마우스 휠 스크롤 (#152) — 수직 / 수평 양축 지원. X11 가로 휠(#149) 및 Win32 고해상도 델타 포함. SmallChange / LargeChange가 모든 RangeBase 컨트롤에서 사용 가능.
  • OS 모달 루프 중 연속 렌더링 (#145) — 네이티브 모달(resize / move / drag) 중에도 애니메이션 및 라이브 프리뷰 업데이트 유지.
  • TRACKMOUSEEVENT 기반 마우스 leave 트래킹 — Win32에서 안정적인 MouseLeave 이벤트 (#148).
  • IPlatformHost DPI 질의 및 오버레이 윈도우 지원 — Win32 GetDpiForPoint, 모든 호스트에서 드래그 프리뷰용 플랫폼 오버레이 윈도우 지원.
  • macOS 글로벌 커서 위치 API — 임의 코드 경로에서 화면 좌표 커서 위치 질의 가능.
  • XInput2(XI2) GenericEvent dispatch (#152) — raw delta 및 축별 스크롤을 위한 모던 X11 입력 파이프라인.
  • Show 이후 OS 수준 윈도우 owner 설정 — 모든 플랫폼에서 owned window가 항상 상위에 유지.

컨트롤

  • 크로스 플랫폼 드래그 앤 드롭 (#93) — Win32 IDropTarget 및 X11 Xdnd 프로토콜 기반 내부/외부 드래그 앤 드롭 라우팅. UIElement.AllowDrop / CanDrag 및 bubbling 이벤트, 드래그 미리보기 오버레이 포함. 윈도우 단위가 아닌 요소 단위로 처리.
  • 창 간 드래그 미리보기OverlayWindow가 Win32 / X11 / macOS의 네이티브 창을 가로질러 드래그 프리뷰를 전달.
    창 간 드래그 미리보기
  • GridView 가변 높이 행 가상화 — 셀 중 가장 큰 높이에 맞춰 행이 측정되며, VariableHeightItemsPresenterInvalidateHeights 추가.
    GridView 가변 높이 행 가상화
  • UIElement.CacheMode 비트맵 렌더 캐싱 — 정적 서브트리를 한 번 래스터화한 후 이후 프레임에 재사용. 요소가 컬링되거나 숨겨지면 캐시 해제.
  • TabPlacement, RotationDecorator — 탭을 임의의 변에 배치 가능. 임의 서브트리 회전 지원.
  • ColorPicker 컨트롤 — HSV 색상 휠, 알파 슬라이더, 16진 입력을 갖춘 드롭다운형 색상 선택기. HsvColor 구조체 함께 추가.
    ColorPicker 컨트롤
  • Grid.ShareStarSize 속성 — 여러 Grid 간 star 크기 공유.
  • NumericUpDown.IsInteger 모드 — 정수 전용 입력.
  • TextBase 선택 속성SelectedText, SelectionStart, SelectionLength를 바인딩 가능하도록 노출.
  • ContextMenu.ShowAt public 공개 — 임의 코드 경로에서 컨텍스트 메뉴 호출 가능.
  • IsToolWindow 플로팅 유틸리티 윈도우 플래그 — 팔레트용 테두리 없는 / 작업 표시줄 미포함 윈도우 모드.
  • Mint 액센트 + enum 기반 액센트 처리 — Mint 프리셋 추가, enum 기반 액센트 해석 정리.
  • TreeView 확장 / 이벤트 리팩터링 (#167) — 명확해진 확장 모델과 전용 이벤트 노출.
    TreeView 확장 및 이벤트 리팩터링
  • ProgressRing.IsActiveMewProperty로 마이그레이션 — 바인딩 가능한 활성화.
  • RotationDecorator, TreeView, Tab용 fluent 확장 메서드 — 새 컨트롤에 대한 체인 가능 구성.

코어

  • AffectsVisualState 특성 — 의존 속성 변경이 시각 상태 갱신을 자동으로 트리거하도록 선언.
  • ISubtreeInvalidationHost — 서브트리 단위 레이아웃 무효화 호스트.
  • 읽기 전용 의존 속성 지원.
  • 바인딩용 WeakEventManager 및 약한 참조 기반 property 전달 — 바인딩이 소스 notifier에 대해 약한 참조를 유지하며, ClearBinding 및 템플릿 unbind 지원으로 깔끔한 해제 가능.
  • BindIsVisible / BindIsEnabled 확장 — 가시성 / 활성화용 컨버터 오버로드를 포함한 fluent 바인딩.

텍스트

  • 텍스트 렌더링 캐싱 강화 — 메뉴 / 동적 텍스트의 레이아웃 재계산과 GPU 텍스처 재할당을 줄여 자주 그려지는 텍스트의 렌더 비용 감소.

진단

  • 계층적 성능 프로파일러 — 레이아웃 / 렌더 / 애니메이션 비용을 프레임 단위로 측정하는 프로파일러와 실시간 오버레이 / 타임라인 디버그 UI. 디버그 빌드에서만 활성화. 오버레이 토글은 Ctrl+Shift+P, 타임라인 윈도우는 Ctrl+Alt+Shift+P.
    Aprillz MewUI Gallery_iFGPxELqEW
  • 비트맵 캐시 무효화 진단 오버레이 — 각 프레임에서 어떤 캐시 서브트리가 다시 그려지는지 시각화.
    Aprillz MewUI Gallery_6WW19flrDq

개선됨

렌더링 / 백엔드

  • 모든 그래픽 백엔드를 *PixelRenderSurface로 통합 — Direct2D는 CPU 읽기 가능형과 GPU(DXGI) 복사 없는 변형 두 가지 제공. GDI는 GdiPixelRenderSurface로 이름 변경.
  • OpenGL 백엔드 비동기 렌더링 지원 — 이미지 필터 등 오프스크린 작업을 워커 스레드에서 처리할 수 있도록 백그라운드 렌더 스코프 추가. 워커가 생성한 텍스처는 UI 스레드에서 픽셀 복사 없이 그대로 사용.
  • MewVG 윈도우 / 컨텍스트 lifecycle 안정화 — Win32 / X11 / macOS 전반에서 컨텍스트 획득, 오프스크린 서피스 provider, 윈도우별 리소스 정리를 공유 계약으로 정렬해 race / leak 가능성 축소.
  • WGL DX interop 및 PBO 업로드 경로 강화 — 컨텍스트 로스 상황에서 WGL_NV_DX_interop 잠금 / 텍스처 lifecycle을 안정화하고, 지속 부하 시 PBO fence 풀의 회수 동작을 견고하게 개선.
  • Metal coverage-AA 첨부 및 presentsWithTransaction 동적 관리.
  • MewVG 백엔드 회전 이미지 AA 적용.
  • 백엔드 프로젝트가 플랫폼 프로젝트를 참조하도록 정리 — 모든 MewUI.Backend.* csproj가 해당 플랫폼의 MewUI.Platform.* 프로젝트를 ProjectReference로 참조하도록 정리하고, 중복 컴파일되던 InlineArrays.cs 등의 공유 타입을 한 곳에서만 빌드하도록 정돈.
  • Win32 윈도우 렌더 타깃의 swap-chain resize / 재사용 — 윈도우 리사이즈마다 swap chain을 파괴하고 재생성하는 동작 제거.
  • GDI+ 컨텍스트가 GpBitmap 기반 DIB 사용 (#153) — 더 나은 DXGI 브리징 및 빠른 이미지 핸드오프.
  • 렌더 루프 스케줄링을 명시적 플래그 기반으로 재구성Continuous / On Request 모드가 기본 모드로 승격되었고, 애니메이션 / 입력 / 무효화에 의한 활성화가 결정론적으로 동작.
  • MewVG 0.5.3으로 갱신.
  • 이미지용 DXGI 브리지 개선 (#153) — D2D / D3D11과 DXGI 소비자 간의 DPI 스케일링 및 서피스 핸드오프 개선.
  • 호버 변경 시 인스펙터 오버레이 redraw 최적화 — 변경된 셀만 무효화.

텍스트

  • CoreText의 CTLine 기반 렌더링 — 측정 너비와 그리기 너비를 일치시켜 정렬 정확도와 커닝 / 합자 처리 개선.
  • PNG 디코더의 1 / 2 / 4-bit grayscale 및 indexed 포맷 지원.
  • Linux 폰트 폴백 안정성 향상.
  • 비활성 창이나 포커스가 없는 컨트롤에서는 텍스트 선택 하이라이트를 숨김.
  • 픽셀 단위 알파 텍스트 렌더링 및 extent 계산 리팩터링 — 회전되거나 비스듬한 텍스트 런(run)에 대해 더 정확한 텍스트 경계.
  • 회전된 텍스트는 텍스트 캐시에서 별도 키로 분리 — 서로 다른 방향 간 재사용 방지.

컨트롤 / 레이아웃

  • Shape 스트레치 처리 — 스트레치 변환을 지오메트리에 베이크해 StrokeThickness가 element-DIP를 유지.
  • ScrollViewer가 Arrange 단계에서 스크롤 상태를 갱신 — Measure 단계의 부작용 제거.
  • ScrollViewer 가변 높이 추정 및 앵커 보정 정확도 향상 — 아이템 크기가 확정되면서 발생하던 뷰포트 점프 완화.
  • 항목 prepend / append / 행 높이 변경 시 스크롤 앵커 유지 — 컬렉션 변화 중에도 사용자가 보고 있던 항목이 뷰포트에 남도록 오프셋 보정.
  • TabControl 내부 ScrollViewer를 제거하고 TabItem 콘텐츠가 독립적으로 ScrollViewer를 사용하도록 수정.
  • 마우스 및 프로그램 입력의 포커스 재지정 개선.
  • 모든 presenter의 아이템 크기를 디바이스 픽셀에 정렬 (#143) — 서브픽셀 경계 어긋남 제거.
  • Border 렌더링 및 metrics refactor — 더 선명한 모서리, 프레임당 할당량 감소.

코어 / 성능

  • 메모리 / GC 부담 전반 감소CollectionPool 도입, PathGeometry 캐시, BorderGeometry 분리, dash pattern stackalloc, BGRA↔RGBA in-place 변환, AccessKey 사전 파싱, FormattedTextStore 측정 제약 캐시 등.
  • MewObject 속성 저장 및 상속 처리 최적화.
  • 디코딩 후 인코딩 바이트 즉시 해제 — 이미지 디코드 직후 인코딩 원본 바이트 배열을 폐기해 메모리 회수.
  • 소유 요소가 컬링 / 숨김 상태일 때 비트맵 렌더 캐시 해제 — 화면 밖 서브트리의 GPU 메모리 회수.
  • 애니메이션 중복 등록 방지 — 동일 애니메이션이 중복 구독되는 것을 막는 안전 장치.
  • 플랫폼 종속 인터페이스 파일을 플랫폼별 폴더로 재배치 — 네임스페이스 동일 (Aprillz.MewUI.Platform.{Win32,MacOS,Linux.X11}).

수정됨

백엔드 / 플랫폼

  • X11 창 종료 시 발생하던 BadDrawable — GL 리소스를 XDestroyWindow보다 먼저 해제하도록 순서 변경.
  • macOS Cmd+\ 시스템 “다음 창” 단축키를 AppKit으로 전달하도록 수정.
  • MewVG Metal 이미지 가장자리 아티팩트 제거.
  • 투명 창에서 발생하던 알파 누적 문제 — 매 프레임 GL framebuffer를 클리어하도록 수정.
  • 회전 / skew 시 텍스트 culling이 전체 transform을 반영하도록 수정 — 잘못된 culling으로 텍스트가 사라지는 문제 해결.
  • macOS 화면 Y축 변환을 top-left origin 기준으로 수정 — 화면 높이만큼 어긋나던 윈도우 배치 보정.
  • 누락된 X11 윈도우 활성화 처리 추가.

컨트롤 / 레이아웃

  • 레이아웃 무효화가 부모로 전파되지 않던 누락 (#125).
  • TabHeaderButton에서 포커스 가능한 자식(닫기 버튼 등)으로의 클릭 위임.
  • 탭 제거 후 잘못 선택되던 항목 보정.
  • Panel 히트 테스트의 Bounds 컬링.
  • ScrollViewer 스크롤 이벤트가 무관한 일시 팝업까지 닫던 동작을 관련 후손으로 한정.
  • Window Adorner 정리 및 클립 / 변환 처리 안정화.

텍스트 / 리소스

  • TextBoxView에서 텍스트가 입력되지 않았을 때의 캐럿 패딩 크기 보정.

Full Changelog: Comparing v0.15.2...v0.16.0 · aprillz/MewUI · GitHub

10 Likes

Aprillz.MewUI.MewCharts

LiveChartsCore엔진을 순수 MewUI IGraphicsContext 백엔드로 컴파일해 동작하는 MewUI용 차트 확장입니다.

SkiaSharp 비의존. LiveChartsCore 엔진(v2.0.4, MIT)을 이 어셈블리에 직접 컴파일해 넣고 MewUI 자체 그래픽 추상화로 그리므로, Win32/macOS/X11 전반의 모든 MewUI 백엔드(Direct2D, GDI, MewVG/OpenGL)에서 렌더링됩니다. 런타임 의존성은 Aprillz.MewUI 하나뿐입니다.

Aprillz MewUI MewCharts Sample_rR2EVDrptn

설치

dotnet add package Aprillz.MewUI.MewCharts

net8.0, net10.0을 대상으로 합니다.

빠른 시작

using Aprillz.MewUI.MewCharts.Views; // 차트 컨트롤 + 시리즈 (CartesianChart, LineSeries<T>, ...)

var chart = new CartesianChart
{
    Series =
    [
        new LineSeries<double>(2, 1, 3, 5, 3, 4, 6),
        new LineSeries<double>(4, 2, 5, 2, 4, 5, 3),
    ],
};

// chart는 MewUI FrameworkElement이므로 어떤 레이아웃에든 넣을 수 있습니다.
window.Content = chart;

차트는 최초 사용 시 MewUI 엔진을 자동 초기화하므로 별도 설정 호출이 필요 없습니다. 테마나 기본값을 미리 구성하려면 시작 시 LiveChartsMewUI.EnsureInitialized()를 한 번 호출하면 됩니다.

차트 컨트롤

셋 다 Aprillz.MewUI.MewCharts.Views에 있으며 ChartViewBase(MewUI Control)를 상속합니다:

컨트롤 인터페이스 용도
CartesianChart ICartesianChartView Line, Area, Column/Bar, Stacked, StepLine, Scatter, Financial, Heat, Box, Error
PieChart IPieChartView Pie, Doughnut, Nightingale, 게이지
PolarChart IPolarChartView Polar line/area, radial

편의 시리즈 타입(LineSeries<T>, ColumnSeries<T>, PieSeries<T>, …)은 Aprillz.MewUI.MewCharts.Views에 있으며 MewUI 기본 geometry/paint를 연결합니다(공식 SkiaSharp 패키지가 하던 역할). 축, 섹션, 페인트, 비주얼 요소는 LiveChartsCore에서 그대로 가져옵니다(Axis, SolidColorPaint, …). 따라서 LiveCharts2 문서와 샘플이 그대로 적용됩니다.

바인딩

차트의 뷰 속성(Series, 축, 제목, 범례/툴팁 페인트와 위치, 줌 모드, 애니메이션 속도, 테마 등)은 다른 MewUI 속성과 동일하게 바인딩 가능합니다. 각 속성 X에는 Bind/SetBinding에 넘길 수 있는 XProperty 필드가 있습니다:

chart.Bind(ChartViewBase.SeriesProperty, source, SourceType.SeriesProperty);

백엔드

MewCharts는 IGraphicsContext만 사용하므로 호스트 앱이 등록한 백엔드 위에서 렌더링됩니다. Direct2D와 MewVG(OpenGL)가 곡선/텍스트 품질이 가장 좋고, GDI도 동작하지만 곡선/텍스트 안티앨리어싱 품질이 떨어집니다.

소스에서 빌드

LiveChartsCore는 git submodule로 가져와 이 어셈블리에 컴파일되므로, 빌드 전에 submodule을 초기화해야 합니다:

git submodule update --init --recursive
dotnet build extensions/MewUI.MewCharts/MewUI.MewCharts.csproj

submodule(ThirdParty/LiveCharts2)은 태그 2.0.4에 고정되며 원본 그대로 유지됩니다. 모든 MewUI 백엔드 코드는 submodule 밖에 있습니다.

샘플

samples/MewUI.MewCharts.Sample은 공식 LiveCharts2 샘플(~75개 섹션)을 충실히 옮긴 갤러리로, 전부 MewCharts로 렌더링됩니다. --gdi 또는 --vg 인자로 백엔드를 전환할 수 있습니다.

알려진 차이/제한

  • 임의 형상 drop shadow는 근사로 처리됩니다(box-shadow는 사각형 기준).
  • 텍스트 메트릭이 SkiaSharp와 미세하게 달라, 일부 회전/멀티라인 라벨이 약간 어긋날 수 있습니다.
  • GeoMap(지도)은 포팅되지 않았습니다.

라이선스

Aprillz.MewUI.MewCharts는 MIT입니다. beto-rodriguez/LiveCharts2의 LiveChartsCore 엔진(MIT)을 포함하며, THIRD_PARTY_NOTICES.md를 참고하세요. SkiaSharp 드로잉 백엔드는 사용하거나 재배포하지 않습니다.


라즈베리파이 4에서도 잘 돌아갑니다.

VNC-Viewer-6 20 113-Windows-64bit_prmJLMZ2GJ

11 Likes

Aprillz.MewUI.Svg

MewUI의 IGraphicsContext로 그리는 MewUI용 SVG 파싱/렌더링 확장입니다.

순수 관리 코드, System.Drawing 비의존. SVG.NET을 기반으로 하되 System.Drawing 렌더링을 MewUI IGraphicsContext 백엔드로 교체했습니다. 따라서 모든 MewUI 백엔드(Direct2D, GDI, MewVG-OpenGL/Metal)에서 SVG를 파싱/렌더링하며 NativeAOT/트리밍 호환입니다.

SVG Icon Sample

Aprillz MewUI Svg Sample_Cbqk1mzdM8

SVG Viewer Sample

Aprillz MewUI Svg Sample_YtvslGFRsb

SVG parsing and rendering for MewUI, drawn through MewUI’s IGraphicsContext.

설치

dotnet add package Aprillz.MewUI.Svg

net8.0, net10.0을 대상으로 합니다.

빠른 시작

SvgImageSource는 표준 Image 컨트롤에 그대로 꽂혀, SVG를 일반 이미지처럼 표시하면서 어떤 크기에서도 선명합니다(비트맵을 늘리는 게 아니라 레이아웃 크기로 다시 그림):

using Aprillz.MewUI.Controls;
using Aprillz.MewUI.Svg;

var image = new Image
{
    Source = SvgImageSource.FromFile("icon.svg"),
    StretchMode = Stretch.Uniform,
}.Size(24, 24);

SvgImageSourceIVectorImageSource라, Image가 매 페인트마다 현재 크기로 벡터를 그립니다. 리사이즈/고DPI에서도 선명합니다.

로딩

SvgImageSource.FromFile(path);                 // 파일 경로
SvgImageSource.FromString(svgMarkup);          // SVG 마크업
SvgImageSource.FromStream(stream);             // 임의 스트림 (예: ZIP 엔트리)
SvgImageSource.FromResource(assembly, name);   // 임베드 리소스

재색칠 (단색 아이콘)

Tint를 설정하면 fill이 상속되는(요소별 명시 fill이 없는) 아이콘을 재색칠합니다. 변경 시 호스트 컨트롤이 자동으로 다시 그립니다:

var source = SvgImageSource.FromFile("home.svg");
source.Tint = theme.Foreground;
new Image { Source = source };
  • IntrinsicSize — SVG viewBox 크기(Image 측정에 사용).
  • RasterWidth / RasterHeightCreateImage 래스터 폴백(픽셀이 필요한 소비자용)에만 영향. 벡터 Image 경로는 무시.

고급: SvgDocument

문서에 직접 접근하려면 SVG.NET 엔진 타입 SvgDocument(네임스페이스 Svg)를 쓸 수 있습니다:

using Svg;

var doc = SvgDocument.Open("icon.svg");   // 또는 .Parse(markup) / .Parse(markup, baseUri)
doc.Render(context, new Rect(0, 0, width, height));   // IGraphicsContext에 그리기

비율 유지에는 doc.ViewBoxWidth / doc.ViewBoxHeight. 대부분의 경우 SvgImageSource + Image를 권장합니다.

백엔드

MewUI.Svg는 IGraphicsContext만 사용하므로 호스트 앱이 등록한 백엔드 위에서 렌더링됩니다. Direct2D와 MewVG(OpenGL)가 곡선/텍스트 품질이 가장 좋고, GDI도 동작하지만 곡선/텍스트 안티앨리어싱 품질이 떨어집니다.

소스에서 빌드

SVG.NET은 git submodule로 가져와 System.Drawing 비의존 소스만 이 어셈블리에 컴파일됩니다. 빌드 전에 submodule을 초기화하세요:

git submodule update --init --recursive
dotnet build extensions/MewUI.Svg/MewUI.Svg.csproj

submodule(ThirdParty/SvgNet)은 원본 그대로 유지됩니다. *.Drawing.cs 렌더링 partial은 제외되고 이 프로젝트의 MewUI *.MewUI.cs partial로 대체됩니다.

의존성

Aprillz.MewUIExCSS(CSS 스타일 파싱). SVG.NET 자체는 컴파일되어 들어가므로 패키지 참조가 아닙니다.

라이선스

Aprillz.MewUI.Svg는 MIT입니다. SVG.NET(Microsoft Public License, Ms-PL) 사본을 포함하며, THIRD_PARTY_NOTICES.md를 참고하세요. System.Drawing은 사용하거나 재배포하지 않습니다.

11 Likes