feat: imagegen2 아이콘·글리프·일러스트 생성 후 GUI 전면 적용 (투명 배경)
codex noninteractive + imagegen2로 앱 비주얼 에셋 일괄 생성, 코드 생성 차단 (gen-one.sh: FORBID 블록 + 코드파일 감지 + 재시도). 모든 산출물은 플러드필 배경 제거로 진짜 알파 투명 PNG화. 생성 에셋 (assets-gen/): - app-master: 앱 아이콘 마스터 (사이클 화살표, 솔리드 타일 유지) - 카테고리 글리프 8종: image/video/audio/document/data/vector/archive/ai - 일러스트 2종: illus-empty(드롭존), illus-done(완료) - logo-mark: 브랜드 마크 GUI 적용: - 사이드바 헤더 브랜드 → logo-mark - 드롭존 빈 상태 → illus-empty - QuickProgressWindow 완료 → illus-done - AI 작업 패널 → glyph-ai 스파클 - 큐/과거결과 행 라벨 아이콘 → 카테고리 글리프 (CategoryGlyphs 매핑) - 미리보기 placeholder → 형식별 카테고리 글리프 (경고 대신) 앱 아이콘: - app.ico (멀티 크기 16~256) + 윈도우 Icon - MSIX 타일 4종(Square44/150·Wide310·Store) app-master 기반 갱신 - Package 버전 1.0.2.0
BIN
assets-gen/app-master.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
55
assets-gen/gen-one.sh
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# gen-one.sh NAME "PROMPT BODY"
|
||||||
|
# codex imagegen2로 단일 PNG 생성. 코드 파일(.py/.svg/.html/.js)을 쓰면 실패로 보고 최대 3회 재시도.
|
||||||
|
set -u
|
||||||
|
NAME="$1"
|
||||||
|
BODY="$2"
|
||||||
|
ROOT="D:/workspace/Everything2Everthing/assets-gen"
|
||||||
|
DEST="$ROOT/$NAME.png"
|
||||||
|
|
||||||
|
for attempt in 1 2 3 4; do
|
||||||
|
WORK="$(mktemp -d)"
|
||||||
|
# 깨끗한 작업 폴더에서만 쓰게 하고, 결과는 out.png 한 장으로 강제
|
||||||
|
PROMPT=$(cat <<PROMPT
|
||||||
|
You have an image generation tool available (imagegen / image_gen). Use it now.
|
||||||
|
|
||||||
|
TASK: Generate a single PNG image and save it in the current working directory as exactly "out.png".
|
||||||
|
|
||||||
|
IMAGE DESCRIPTION:
|
||||||
|
$BODY
|
||||||
|
|
||||||
|
ABSOLUTE RULES — violating any of these is a hard failure:
|
||||||
|
- You MUST call the image generation tool to produce the picture.
|
||||||
|
- DO NOT write, create, or edit ANY code file of ANY kind: no .py, .svg, .html, .js, .ts, .sh, .json, no Python, no PIL/Pillow, no matplotlib, no cairo, no SVG markup, no canvas, no ASCII art.
|
||||||
|
- DO NOT try to "draw" or "render" the image with code. If you are even slightly tempted to script it, STOP and use the image generation tool instead.
|
||||||
|
- The ONLY file that may exist when you finish is out.png produced by the image generation tool.
|
||||||
|
- After saving, reply with just: DONE
|
||||||
|
PROMPT
|
||||||
|
)
|
||||||
|
echo "$PROMPT" | codex exec --skip-git-repo-check --sandbox workspace-write -C "$WORK" --ephemeral - >/dev/null 2>&1
|
||||||
|
|
||||||
|
# 코드 파일을 썼는지 검사
|
||||||
|
CODE=$(find "$WORK" -type f \( -name '*.py' -o -name '*.svg' -o -name '*.html' -o -name '*.js' -o -name '*.ts' -o -name '*.sh' \) 2>/dev/null | head -1)
|
||||||
|
PNG=$(find "$WORK" -type f -name '*.png' 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if [ -n "$CODE" ]; then
|
||||||
|
echo "[$NAME] attempt $attempt: codex wrote CODE ($CODE) — reject, retry"
|
||||||
|
rm -rf "$WORK"; continue
|
||||||
|
fi
|
||||||
|
if [ -z "$PNG" ]; then
|
||||||
|
echo "[$NAME] attempt $attempt: no PNG produced — retry"
|
||||||
|
rm -rf "$WORK"; continue
|
||||||
|
fi
|
||||||
|
# 너무 작은 PNG(코드로 만든 단색/플레이스홀더)도 거부
|
||||||
|
SZ=$(stat -c%s "$PNG" 2>/dev/null || echo 0)
|
||||||
|
if [ "$SZ" -lt 120000 ]; then
|
||||||
|
echo "[$NAME] attempt $attempt: PNG too small ($SZ bytes) — likely synthetic, retry"
|
||||||
|
rm -rf "$WORK"; continue
|
||||||
|
fi
|
||||||
|
cp "$PNG" "$DEST"
|
||||||
|
echo "[$NAME] OK ($SZ bytes) -> $DEST"
|
||||||
|
rm -rf "$WORK"
|
||||||
|
exit 0
|
||||||
|
done
|
||||||
|
echo "[$NAME] FAILED after retries"
|
||||||
|
exit 1
|
||||||
BIN
assets-gen/glyph-ai.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
assets-gen/glyph-archive.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
assets-gen/glyph-audio.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
assets-gen/glyph-data.png
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
BIN
assets-gen/glyph-document.png
Normal file
|
After Width: | Height: | Size: 2 MiB |
BIN
assets-gen/glyph-image.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
assets-gen/glyph-vector.png
Normal file
|
After Width: | Height: | Size: 2 MiB |
BIN
assets-gen/glyph-video.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
assets-gen/illus-done.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
assets-gen/illus-empty.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
assets-gen/logo-mark.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 670 B After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 729 B After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 41 KiB |
|
|
@ -12,7 +12,7 @@
|
||||||
<Identity
|
<Identity
|
||||||
Name="Everything2Everything.YunChan"
|
Name="Everything2Everything.YunChan"
|
||||||
Publisher="CN=Everything2EverythingDev"
|
Publisher="CN=Everything2EverythingDev"
|
||||||
Version="1.0.0.0"
|
Version="1.0.2.0"
|
||||||
ProcessorArchitecture="x64" />
|
ProcessorArchitecture="x64" />
|
||||||
|
|
||||||
<Properties>
|
<Properties>
|
||||||
|
|
|
||||||
BIN
src/Everything2Everything.App/Assets/app-icon.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
src/Everything2Everything.App/Assets/glyph-ai.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
src/Everything2Everything.App/Assets/glyph-archive.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
src/Everything2Everything.App/Assets/glyph-audio.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
src/Everything2Everything.App/Assets/glyph-data.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
src/Everything2Everything.App/Assets/glyph-document.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
src/Everything2Everything.App/Assets/glyph-image.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
src/Everything2Everything.App/Assets/glyph-vector.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
src/Everything2Everything.App/Assets/glyph-video.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
src/Everything2Everything.App/Assets/illus-done.png
Normal file
|
After Width: | Height: | Size: 260 KiB |
BIN
src/Everything2Everything.App/Assets/illus-empty.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
src/Everything2Everything.App/Assets/logo-mark.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
|
|
@ -9,6 +9,7 @@
|
||||||
<AssemblyName>Everything2Everything</AssemblyName>
|
<AssemblyName>Everything2Everything</AssemblyName>
|
||||||
<RootNamespace>Everything2Everything.App</RootNamespace>
|
<RootNamespace>Everything2Everything.App</RootNamespace>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
<ApplicationIcon>app.ico</ApplicationIcon>
|
||||||
<SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
<NoWarn>$(NoWarn);NU1901;NU1902;NU1903;NU1904</NoWarn>
|
<NoWarn>$(NoWarn);NU1901;NU1902;NU1903;NU1904</NoWarn>
|
||||||
|
|
@ -26,4 +27,9 @@
|
||||||
<Using Include="System.IO" />
|
<Using Include="System.IO" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- 인앱 일러스트·글리프·브랜드 마크 (imagegen2 생성) -->
|
||||||
|
<ItemGroup>
|
||||||
|
<Resource Include="Assets\**\*.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
63
src/Everything2Everything.App/Views/CategoryGlyphs.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
|
namespace Everything2Everything.App.Views;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 파일 확장자 → 카테고리 글리프(imagegen2 생성 PNG) 매핑.
|
||||||
|
/// 큐 행·미리보기 placeholder 등에서 형식을 한눈에 보여주기 위해 사용한다.
|
||||||
|
/// </summary>
|
||||||
|
public static class CategoryGlyphs
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<string, string> ExtToCategory = new(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
// image
|
||||||
|
[".jpg"] = "image", [".jpeg"] = "image", [".jpe"] = "image", [".png"] = "image",
|
||||||
|
[".webp"] = "image", [".avif"] = "image", [".bmp"] = "image", [".tif"] = "image",
|
||||||
|
[".tiff"] = "image", [".gif"] = "image", [".heic"] = "image", [".heif"] = "image",
|
||||||
|
[".cr2"] = "image", [".nef"] = "image", [".arw"] = "image", [".dng"] = "image", [".raw"] = "image",
|
||||||
|
// vector
|
||||||
|
[".svg"] = "vector", [".eps"] = "vector", [".ai"] = "vector",
|
||||||
|
// video
|
||||||
|
[".mp4"] = "video", [".webm"] = "video", [".mkv"] = "video", [".mov"] = "video", [".avi"] = "video",
|
||||||
|
// audio
|
||||||
|
[".mp3"] = "audio", [".aac"] = "audio", [".m4a"] = "audio", [".opus"] = "audio",
|
||||||
|
[".ogg"] = "audio", [".flac"] = "audio", [".wav"] = "audio",
|
||||||
|
// document
|
||||||
|
[".pdf"] = "document", [".docx"] = "document", [".doc"] = "document",
|
||||||
|
[".hwp"] = "document", [".hwpx"] = "document", [".html"] = "document", [".htm"] = "document",
|
||||||
|
[".md"] = "document", [".txt"] = "document", [".rtf"] = "document",
|
||||||
|
// data
|
||||||
|
[".csv"] = "data", [".json"] = "data", [".xlsx"] = "data", [".xls"] = "data",
|
||||||
|
[".tsv"] = "data", [".xml"] = "data", [".yaml"] = "data", [".yml"] = "data",
|
||||||
|
// archive
|
||||||
|
[".zip"] = "archive", [".7z"] = "archive", [".rar"] = "archive",
|
||||||
|
[".tar"] = "archive", [".gz"] = "archive",
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, ImageSource> Cache = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
/// <summary>확장자(.jpg 등)에 해당하는 카테고리 글리프 이미지. 매핑이 없으면 document로 폴백.</summary>
|
||||||
|
public static ImageSource ForExtension(string? extension)
|
||||||
|
{
|
||||||
|
var ext = string.IsNullOrWhiteSpace(extension) ? "" : extension.Trim();
|
||||||
|
if (ext.Length > 0 && ext[0] != '.') ext = "." + ext;
|
||||||
|
var category = ExtToCategory.TryGetValue(ext, out var c) ? c : "document";
|
||||||
|
return ForCategory(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>카테고리명(image/video/audio/document/data/vector/archive/ai)에 해당하는 글리프.</summary>
|
||||||
|
public static ImageSource ForCategory(string category)
|
||||||
|
{
|
||||||
|
if (Cache.TryGetValue(category, out var cached)) return cached;
|
||||||
|
var uri = new Uri($"pack://application:,,,/Assets/glyph-{category}.png", UriKind.Absolute);
|
||||||
|
var img = new BitmapImage();
|
||||||
|
img.BeginInit();
|
||||||
|
img.CacheOption = BitmapCacheOption.OnLoad;
|
||||||
|
img.UriSource = uri;
|
||||||
|
img.EndInit();
|
||||||
|
img.Freeze();
|
||||||
|
Cache[category] = img;
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||||
Title="FormatShift Utility"
|
Title="FormatShift Utility"
|
||||||
|
Icon="pack://application:,,,/Assets/app-icon.png"
|
||||||
Width="1280" Height="960"
|
Width="1280" Height="960"
|
||||||
MinWidth="1080" MinHeight="640"
|
MinWidth="1080" MinHeight="640"
|
||||||
ExtendsContentIntoTitleBar="True"
|
ExtendsContentIntoTitleBar="True"
|
||||||
|
|
@ -62,10 +63,10 @@
|
||||||
<Border Grid.Row="0" BorderBrush="{StaticResource FsBorderSubtle}"
|
<Border Grid.Row="0" BorderBrush="{StaticResource FsBorderSubtle}"
|
||||||
BorderThickness="0,0,0,1" Padding="24,0">
|
BorderThickness="0,0,0,1" Padding="24,0">
|
||||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||||
<Path Width="18" Height="18" Stretch="Uniform"
|
<Image Width="22" Height="22"
|
||||||
Stroke="{StaticResource FsAccentBlue}" StrokeThickness="2"
|
RenderOptions.BitmapScalingMode="HighQuality"
|
||||||
Data="M3,3 L21,3 L21,21 L3,21 Z M12,8 L12,16 M8,12 L16,12"/>
|
Source="pack://application:,,,/Assets/logo-mark.png"/>
|
||||||
<TextBlock Margin="8,0,0,0" FontSize="14" FontWeight="SemiBold"
|
<TextBlock Margin="9,0,0,0" FontSize="14" FontWeight="SemiBold"
|
||||||
Foreground="{StaticResource FsTextPrimary}"
|
Foreground="{StaticResource FsTextPrimary}"
|
||||||
FontFamily="{StaticResource FsFontSans}">
|
FontFamily="{StaticResource FsFontSans}">
|
||||||
FormatShift
|
FormatShift
|
||||||
|
|
@ -192,7 +193,12 @@
|
||||||
|
|
||||||
<!-- AI Task -->
|
<!-- AI Task -->
|
||||||
<StackPanel x:Name="AiTaskPanel" Margin="0,0,0,32">
|
<StackPanel x:Name="AiTaskPanel" Margin="0,0,0,32">
|
||||||
<TextBlock Text="AI 작업" Style="{StaticResource FsLabelStyle}"/>
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Image Width="15" Height="15" VerticalAlignment="Center" Margin="0,0,6,0"
|
||||||
|
RenderOptions.BitmapScalingMode="HighQuality"
|
||||||
|
Source="pack://application:,,,/Assets/glyph-ai.png"/>
|
||||||
|
<TextBlock Text="AI 작업" Style="{StaticResource FsLabelStyle}" VerticalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
<ComboBox x:Name="AiTaskCombo" Margin="0,8,0,0"
|
<ComboBox x:Name="AiTaskCombo" Margin="0,8,0,0"
|
||||||
SelectedIndex="0"
|
SelectedIndex="0"
|
||||||
SelectionChanged="OnAiTaskChanged">
|
SelectionChanged="OnAiTaskChanged">
|
||||||
|
|
@ -401,12 +407,12 @@
|
||||||
StrokeDashArray="5 4"
|
StrokeDashArray="5 4"
|
||||||
Fill="#04FFFFFF"/>
|
Fill="#04FFFFFF"/>
|
||||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||||
Margin="48,56">
|
Margin="48,52">
|
||||||
<Path Width="44" Height="44" Stretch="Uniform"
|
<Image Width="128" Height="128"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Stroke="{StaticResource FsAccentBlue}" StrokeThickness="1.5"
|
RenderOptions.BitmapScalingMode="HighQuality"
|
||||||
Data="M21,15 L21,19 C21,20.1 20.1,21 19,21 L5,21 C3.9,21 3,20.1 3,19 L3,15 M7,10 L12,15 L17,10 M12,15 L12,3"/>
|
Source="pack://application:,,,/Assets/illus-empty.png"/>
|
||||||
<TextBlock Margin="0,18,0,0" FontSize="16" FontWeight="SemiBold"
|
<TextBlock Margin="0,16,0,0" FontSize="16" FontWeight="SemiBold"
|
||||||
Foreground="{StaticResource FsTextPrimary}"
|
Foreground="{StaticResource FsTextPrimary}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Text="Drop files anywhere to queue"/>
|
Text="Drop files anywhere to queue"/>
|
||||||
|
|
@ -459,15 +465,9 @@
|
||||||
<ColumnDefinition Width="120"/>
|
<ColumnDefinition Width="120"/>
|
||||||
<ColumnDefinition Width="40"/>
|
<ColumnDefinition Width="40"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Border Width="32" Height="32" CornerRadius="4"
|
<Image Width="34" Height="34" VerticalAlignment="Center"
|
||||||
Background="{Binding FormatBrush}"
|
RenderOptions.BitmapScalingMode="HighQuality"
|
||||||
VerticalAlignment="Center">
|
Source="{Binding GlyphSource}"/>
|
||||||
<TextBlock Text="{Binding FormatLabel}"
|
|
||||||
Foreground="White" FontSize="10"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"/>
|
|
||||||
</Border>
|
|
||||||
<StackPanel Grid.Column="1" Margin="16,0,0,0"
|
<StackPanel Grid.Column="1" Margin="16,0,0,0"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center">
|
||||||
<TextBlock Text="{Binding FileName}"
|
<TextBlock Text="{Binding FileName}"
|
||||||
|
|
@ -570,15 +570,9 @@
|
||||||
<ColumnDefinition Width="40"/>
|
<ColumnDefinition Width="40"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Border Width="32" Height="32" CornerRadius="4"
|
<Image Width="34" Height="34" VerticalAlignment="Center"
|
||||||
Background="{Binding FormatBrush}"
|
RenderOptions.BitmapScalingMode="HighQuality"
|
||||||
VerticalAlignment="Center">
|
Source="{Binding GlyphSource}"/>
|
||||||
<TextBlock Text="{Binding FormatLabel}"
|
|
||||||
Foreground="White" FontSize="10"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"/>
|
|
||||||
</Border>
|
|
||||||
|
|
||||||
<StackPanel Grid.Column="1" Margin="16,0,0,0"
|
<StackPanel Grid.Column="1" Margin="16,0,0,0"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center">
|
||||||
|
|
@ -707,7 +701,10 @@
|
||||||
<!-- Reason -->
|
<!-- Reason -->
|
||||||
<StackPanel x:Name="PreviewReason" Visibility="Collapsed"
|
<StackPanel x:Name="PreviewReason" Visibility="Collapsed"
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20">
|
HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20">
|
||||||
<Path Width="32" Height="32" Stretch="Uniform"
|
<Image x:Name="PreviewGlyph" Width="84" Height="84"
|
||||||
|
HorizontalAlignment="Center" Visibility="Collapsed"
|
||||||
|
RenderOptions.BitmapScalingMode="HighQuality"/>
|
||||||
|
<Path x:Name="PreviewWarnIcon" Width="32" Height="32" Stretch="Uniform"
|
||||||
Stroke="{StaticResource FsAccentAmber}" StrokeThickness="1.5"
|
Stroke="{StaticResource FsAccentAmber}" StrokeThickness="1.5"
|
||||||
Data="M12,2 L22,20 L2,20 Z M12,9 L12,14 M12,17 L12,17.01"/>
|
Data="M12,2 L22,20 L2,20 Z M12,9 L12,14 M12,17 L12,17.01"/>
|
||||||
<TextBlock x:Name="PreviewReasonText" Margin="0,12,0,0"
|
<TextBlock x:Name="PreviewReasonText" Margin="0,12,0,0"
|
||||||
|
|
|
||||||
|
|
@ -393,8 +393,10 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PreviewReasonText.Text = result.Reason ?? "미리보기를 생성하지 못했습니다.";
|
// 래스터 미리보기가 없는 형식(영상·오디오·문서·데이터 등)은 경고 대신 카테고리 글리프로 표현
|
||||||
PreviewReason.Visibility = Visibility.Visible;
|
ShowPreviewGlyph(
|
||||||
|
System.IO.Path.GetExtension(sourcePath),
|
||||||
|
result.Reason ?? "이 형식은 미리보기를 만들 수 없습니다. 변환은 정상 동작합니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
PreviewDimText.Text = result.Dimensions ?? "—";
|
PreviewDimText.Text = result.Dimensions ?? "—";
|
||||||
|
|
@ -431,6 +433,21 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
|
||||||
PreviewEmpty.Visibility = Visibility.Collapsed;
|
PreviewEmpty.Visibility = Visibility.Collapsed;
|
||||||
PreviewImage.Visibility = Visibility.Collapsed;
|
PreviewImage.Visibility = Visibility.Collapsed;
|
||||||
PreviewLoading.Visibility = Visibility.Collapsed;
|
PreviewLoading.Visibility = Visibility.Collapsed;
|
||||||
|
PreviewGlyph.Visibility = Visibility.Collapsed;
|
||||||
|
PreviewWarnIcon.Visibility = Visibility.Visible;
|
||||||
|
PreviewReasonText.Text = reason;
|
||||||
|
PreviewReason.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>래스터 미리보기가 없는 형식은 경고 대신 카테고리 글리프로 안내한다.</summary>
|
||||||
|
private void ShowPreviewGlyph(string? extension, string reason)
|
||||||
|
{
|
||||||
|
PreviewEmpty.Visibility = Visibility.Collapsed;
|
||||||
|
PreviewImage.Visibility = Visibility.Collapsed;
|
||||||
|
PreviewLoading.Visibility = Visibility.Collapsed;
|
||||||
|
PreviewGlyph.Source = CategoryGlyphs.ForExtension(extension);
|
||||||
|
PreviewGlyph.Visibility = Visibility.Visible;
|
||||||
|
PreviewWarnIcon.Visibility = Visibility.Collapsed;
|
||||||
PreviewReasonText.Text = reason;
|
PreviewReasonText.Text = reason;
|
||||||
PreviewReason.Visibility = Visibility.Visible;
|
PreviewReason.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
@ -1120,6 +1137,9 @@ public sealed class QueueItem : INotifyPropertyChanged
|
||||||
public required string MetaLine { get; init; }
|
public required string MetaLine { get; init; }
|
||||||
public required long SourceSizeBytes { get; init; }
|
public required long SourceSizeBytes { get; init; }
|
||||||
|
|
||||||
|
/// <summary>형식 카테고리 글리프(라벨 아이콘).</summary>
|
||||||
|
public System.Windows.Media.ImageSource GlyphSource => CategoryGlyphs.ForExtension(Path.GetExtension(SourcePath));
|
||||||
|
|
||||||
public string StateText
|
public string StateText
|
||||||
{
|
{
|
||||||
get => _state;
|
get => _state;
|
||||||
|
|
@ -1225,6 +1245,9 @@ public sealed record HistoryRow(
|
||||||
{
|
{
|
||||||
public string RevealPath => OutputPath ?? SourcePath;
|
public string RevealPath => OutputPath ?? SourcePath;
|
||||||
|
|
||||||
|
/// <summary>형식 카테고리 글리프(라벨 아이콘).</summary>
|
||||||
|
public System.Windows.Media.ImageSource GlyphSource => CategoryGlyphs.ForExtension(Path.GetExtension(SourcePath));
|
||||||
|
|
||||||
public static HistoryRow From(HistoryEntry e)
|
public static HistoryRow From(HistoryEntry e)
|
||||||
{
|
{
|
||||||
var ext = Path.GetExtension(e.SourcePath).TrimStart('.').ToLowerInvariant();
|
var ext = Path.GetExtension(e.SourcePath).TrimStart('.').ToLowerInvariant();
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||||
Title="빠른 변환"
|
Title="빠른 변환"
|
||||||
Width="560" Height="220"
|
Width="560" Height="240"
|
||||||
ExtendsContentIntoTitleBar="True"
|
ExtendsContentIntoTitleBar="True"
|
||||||
WindowBackdropType="Mica"
|
WindowBackdropType="Mica"
|
||||||
WindowCornerPreference="Round"
|
WindowCornerPreference="Round"
|
||||||
|
|
@ -36,6 +36,11 @@
|
||||||
Style="{StaticResource TextCaption}" TextTrimming="CharacterEllipsis"/>
|
Style="{StaticResource TextCaption}" TextTrimming="CharacterEllipsis"/>
|
||||||
<ProgressBar x:Name="OverallProgress" Grid.Row="2" Height="6"
|
<ProgressBar x:Name="OverallProgress" Grid.Row="2" Height="6"
|
||||||
Minimum="0" Maximum="1"/>
|
Minimum="0" Maximum="1"/>
|
||||||
|
<Image x:Name="DoneIllustration" Grid.Row="3" Visibility="Collapsed"
|
||||||
|
Width="96" Height="96" Margin="0,8,0,0"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||||
|
RenderOptions.BitmapScalingMode="HighQuality"
|
||||||
|
Source="pack://application:,,,/Assets/illus-done.png"/>
|
||||||
<StackPanel Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0">
|
<StackPanel Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0">
|
||||||
<ui:Button x:Name="OpenFolderButton" Content="결과 폴더 열기"
|
<ui:Button x:Name="OpenFolderButton" Content="결과 폴더 열기"
|
||||||
Icon="{ui:SymbolIcon Folder24}"
|
Icon="{ui:SymbolIcon Folder24}"
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,12 @@ public partial class QuickProgressWindow : FluentWindow
|
||||||
OpenInExplorer(_firstSuccessOutput);
|
OpenInExplorer(_firstSuccessOutput);
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
else if (failed == 0 && success > 0)
|
||||||
|
{
|
||||||
|
// 전부 성공했지만 일부 건너뛰어 창이 남는 경우 — 완료 일러스트로 마무리
|
||||||
|
DoneIllustration.Visibility = Visibility.Visible;
|
||||||
|
Height = 360;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnOpenFolderClick(object sender, RoutedEventArgs e)
|
private void OnOpenFolderClick(object sender, RoutedEventArgs e)
|
||||||
|
|
|
||||||
BIN
src/Everything2Everything.App/app.ico
Normal file
|
After Width: | Height: | Size: 151 KiB |