Public Access
Merge branch 'claude/connection-host-default-text-9e501d'
This commit is contained in:
@@ -1,25 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!--
|
<!--
|
||||||
The launcher mark, and it is the same mark ServerScreen and LockedScreen draw: a square
|
The launcher mark, and it is the same mark PhoneShell's header and the desktop titlebar draw:
|
||||||
outline in the accent with >_ inside it. Redrawn as a vector rather than exported as a
|
>_ in the canvas colour on a solid accent tile. Filled rather than outlined since v2.
|
||||||
bitmap so there is one geometry to change and no set of five PNG densities to forget one
|
|
||||||
of.
|
|
||||||
|
|
||||||
#5B8CFF is AccentColor from DodoSSH.Client.Shell's Theme/Palette.axaml, written out
|
The tile is not in this file. It is the background layer — @color/dodo_accent, see ic_launcher.xml
|
||||||
because an Android resource cannot reference a XAML dictionary. The same duplication
|
— and that is the whole trick of the filled design on Android: the rounding a launcher applies is
|
||||||
colors.xml already carries for the window background, and the same rule applies: if the
|
its mask, so letting the mask make the tile gets a squircle on one device and a circle on another
|
||||||
palette moves, this moves with it.
|
without either being drawn here. A rounded rectangle painted into this layer would be a second
|
||||||
|
rounded shape inside the first, visibly clipped at the corners on any device whose mask is not the
|
||||||
|
one it was drawn for.
|
||||||
|
|
||||||
108x108 with the artwork inside the middle 72 is the adaptive-icon contract — the outer
|
#0E1220 is AccentInk from DodoSSH.Client.Shell's Theme/Palette.axaml, written out because an
|
||||||
18 on each edge is what the launcher eats for masking and parallax. That 72 is a width,
|
Android resource cannot reference a XAML dictionary. It equals Canvas today and is named
|
||||||
though, and the mark is a square: its corners are what a circular mask reaches first. At
|
separately in the palette for a reason worth keeping in mind here: this is ink on the accent, not
|
||||||
48 across the corners land 33.9 out against a radius of 36 and read as clipped even
|
the window behind it, and it follows AccentInk if the two ever part.
|
||||||
though they technically clear it. 42 puts them at 29.7, which is margin one can see.
|
|
||||||
|
|
||||||
The stroke widths are the one place this deliberately departs from the screen. In the app
|
108x108 with the artwork inside the middle 72 is the adaptive-icon contract — the outer 18 on each
|
||||||
the box is a 1px border on 44px; scaled honestly that would be 1.0 here, and a launcher
|
edge is what the launcher eats for masking and parallax. The glyph spans 36.06..71.94, which is
|
||||||
drawing this at 48dp would render it at half a pixel and show nothing. 2.2 and 2.8 are
|
half the width of that 72 and centred in it. That half is taken from the headers rather than
|
||||||
what keep it reading as the same hairline mark at the size it is actually looked at.
|
invented: the phone draws >_ at font size 10 on a 26px tile and the titlebar at 9 on 20px, both a
|
||||||
|
little under half the tile across, and a launcher icon is looked at from further away than either.
|
||||||
|
|
||||||
|
The stroke width is the one place this deliberately departs from the screen. In the app the glyph
|
||||||
|
is a bold mono face whose stems come out near a fifth of its height; 5.4 here is nearer a quarter,
|
||||||
|
which is what keeps it reading as the same mark at the size it is actually looked at.
|
||||||
-->
|
-->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
@@ -27,28 +31,21 @@
|
|||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
|
|
||||||
<!-- The box: 42 across, centred, square-cornered as the Border in the app is. -->
|
|
||||||
<path
|
|
||||||
android:pathData="M33,33 L75,33 L75,75 L33,75 Z"
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:strokeColor="#5B8CFF"
|
|
||||||
android:strokeWidth="2.2" />
|
|
||||||
|
|
||||||
<!-- The chevron of >_ -->
|
<!-- The chevron of >_ -->
|
||||||
<path
|
<path
|
||||||
android:pathData="M44.8,48.75 L51.9,54 L44.8,59.25"
|
android:pathData="M36.06,43.33 L49.91,53.57 L36.06,63.8"
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:strokeColor="#5B8CFF"
|
android:strokeColor="#0E1220"
|
||||||
android:strokeWidth="2.8"
|
android:strokeWidth="5.4"
|
||||||
android:strokeLineCap="round"
|
android:strokeLineCap="round"
|
||||||
android:strokeLineJoin="round" />
|
android:strokeLineJoin="round" />
|
||||||
|
|
||||||
<!-- The underscore, on the baseline the chevron bottoms out at. -->
|
<!-- The underscore, on the baseline the chevron bottoms out at. -->
|
||||||
<path
|
<path
|
||||||
android:pathData="M54,59.7 L63.2,59.7"
|
android:pathData="M54,64.68 L71.94,64.68"
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:strokeColor="#5B8CFF"
|
android:strokeColor="#0E1220"
|
||||||
android:strokeWidth="2.8"
|
android:strokeWidth="5.4"
|
||||||
android:strokeLineCap="round" />
|
android:strokeLineCap="round" />
|
||||||
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -4,9 +4,14 @@
|
|||||||
the wallpaper's colours. The system tints this by its alpha and discards the colour, so
|
the wallpaper's colours. The system tints this by its alpha and discards the colour, so
|
||||||
the geometry is the foreground's and white is only a way of saying "opaque here".
|
the geometry is the foreground's and white is only a way of saying "opaque here".
|
||||||
|
|
||||||
|
Note what that means for the filled design: the accent tile is the background layer, and a
|
||||||
|
themed icon drops the background entirely. So the shape that survives here is the glyph, not
|
||||||
|
the tile — which is the right way round anyway. Filling this layer to the edges to stand in
|
||||||
|
for the tile would tint to a featureless square with nothing of the mark left in it.
|
||||||
|
|
||||||
Worth shipping rather than leaving out: a launcher with themed icons on and no monochrome
|
Worth shipping rather than leaving out: a launcher with themed icons on and no monochrome
|
||||||
layer to use falls back to the full-colour icon, so the one app on the home screen still
|
layer to use falls back to the full-colour icon, so the one app on the home screen still
|
||||||
drawn in green is this one.
|
drawn in blue is this one.
|
||||||
-->
|
-->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
@@ -15,24 +20,18 @@
|
|||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:pathData="M33,33 L75,33 L75,75 L33,75 Z"
|
android:pathData="M36.06,43.33 L49.91,53.57 L36.06,63.8"
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:strokeColor="#FFFFFF"
|
android:strokeColor="#FFFFFF"
|
||||||
android:strokeWidth="2.2" />
|
android:strokeWidth="5.4"
|
||||||
|
|
||||||
<path
|
|
||||||
android:pathData="M44.8,48.75 L51.9,54 L44.8,59.25"
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:strokeColor="#FFFFFF"
|
|
||||||
android:strokeWidth="2.8"
|
|
||||||
android:strokeLineCap="round"
|
android:strokeLineCap="round"
|
||||||
android:strokeLineJoin="round" />
|
android:strokeLineJoin="round" />
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:pathData="M54,59.7 L63.2,59.7"
|
android:pathData="M54,64.68 L71.94,64.68"
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:strokeColor="#FFFFFF"
|
android:strokeColor="#FFFFFF"
|
||||||
android:strokeWidth="2.8"
|
android:strokeWidth="5.4"
|
||||||
android:strokeLineCap="round" />
|
android:strokeLineCap="round" />
|
||||||
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -5,12 +5,17 @@
|
|||||||
adaptive icons landed in 26, so there is no device this ships to that would need the
|
adaptive icons landed in 26, so there is no device this ships to that would need the
|
||||||
bitmaps. Density buckets exist to pick a PNG; a vector has nothing to pick between.
|
bitmaps. Density buckets exist to pick a PNG; a vector has nothing to pick between.
|
||||||
|
|
||||||
The background is the same @color/dodo_window the window, status bar and navigation bar
|
The background is the accent, and that is the tile itself rather than a backdrop for one:
|
||||||
use, so the mark sits on the app's own near-black rather than on a second dark that is
|
the v2 mark is >_ knocked out of a solid accent square, so the square is this layer and the
|
||||||
almost but not quite it.
|
launcher's mask is what rounds it. See ic_launcher_foreground.xml for why the rounding is
|
||||||
|
left to the mask instead of drawn.
|
||||||
|
|
||||||
|
It was @color/dodo_window until the mark went from outlined to filled, which is worth
|
||||||
|
knowing if a home screen still shows the dark version: a launcher caches icons, and the
|
||||||
|
cache outlives the install that changed them.
|
||||||
-->
|
-->
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@color/dodo_window" />
|
<background android:drawable="@color/dodo_accent" />
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
|
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
|
|||||||
@@ -10,4 +10,11 @@
|
|||||||
hidden.
|
hidden.
|
||||||
-->
|
-->
|
||||||
<color name="dodo_window">#0E1220</color>
|
<color name="dodo_window">#0E1220</color>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
AccentColor from the same palette, here because the launcher icon's background layer is a colour
|
||||||
|
and not a drawable. Same hand-kept duplication as above, and the same rule: if the palette moves,
|
||||||
|
this moves with it.
|
||||||
|
-->
|
||||||
|
<color name="dodo_accent">#5B8CFF</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -11,15 +11,19 @@
|
|||||||
# Coordinates are the launcher's 108-unit viewport, mapped so the middle 72 fills the canvas.
|
# Coordinates are the launcher's 108-unit viewport, mapped so the middle 72 fills the canvas.
|
||||||
# That 72 is not an arbitrary crop: it is the part of an adaptive icon a launcher actually shows,
|
# That 72 is not an arbitrary crop: it is the part of an adaptive icon a launcher actually shows,
|
||||||
# the outer 18 on each edge being what it eats for masking and parallax. Rendering the whole 108
|
# the outer 18 on each edge being what it eats for masking and parallax. Rendering the whole 108
|
||||||
# here would draw the mark at 39% of the width — correct arithmetic, and a stamp lost in a field
|
# here would draw the glyph at half the size it is meant to be — correct arithmetic, and a stamp
|
||||||
# of background. Matching what the phone displays means matching the 72.
|
# lost in a field of accent. Matching what the phone displays means matching the 72.
|
||||||
|
#
|
||||||
|
# The one thing this draws that the phone's vector does not is the tile. On Android the tile is
|
||||||
|
# the background layer and the launcher's mask rounds it; Windows has no mask, so the rounding
|
||||||
|
# happens here.
|
||||||
|
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
Add-Type -AssemblyName System.Drawing
|
Add-Type -AssemblyName System.Drawing
|
||||||
|
|
||||||
$window = [System.Drawing.ColorTranslator]::FromHtml('#0E1220') # dodo_window / CanvasColor
|
$accent = [System.Drawing.ColorTranslator]::FromHtml('#5B8CFF') # dodo_accent / AccentColor
|
||||||
$accent = [System.Drawing.ColorTranslator]::FromHtml('#5B8CFF') # AccentColor
|
$ink = [System.Drawing.ColorTranslator]::FromHtml('#0E1220') # AccentInk
|
||||||
|
|
||||||
# Every size Windows asks for: 16 in a titlebar and a tree, 32 on the desktop, 48 in a large-icon
|
# Every size Windows asks for: 16 in a titlebar and a tree, 32 on the desktop, 48 in a large-icon
|
||||||
# view, 256 for the preview pane. Shipping fewer means Windows downsamples one of these to fill
|
# view, 256 for the preview pane. Shipping fewer means Windows downsamples one of these to fill
|
||||||
@@ -33,7 +37,7 @@ function New-MarkPng([int]$size)
|
|||||||
$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
|
$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
|
||||||
$g.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality
|
$g.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality
|
||||||
|
|
||||||
# The background, rounded as a launcher mask rounds it. A square-cornered tile would be the
|
# The accent tile, rounded as a launcher mask rounds it. A square-cornered tile would be the
|
||||||
# one icon on the taskbar with corners, which reads as unfinished rather than as deliberate.
|
# one icon on the taskbar with corners, which reads as unfinished rather than as deliberate.
|
||||||
$radius = [double]$size * 0.22
|
$radius = [double]$size * 0.22
|
||||||
$d = $radius * 2.0
|
$d = $radius * 2.0
|
||||||
@@ -43,7 +47,7 @@ function New-MarkPng([int]$size)
|
|||||||
$path.AddArc($size - $d, $size - $d, $d, $d, 0, 90)
|
$path.AddArc($size - $d, $size - $d, $d, $d, 0, 90)
|
||||||
$path.AddArc(0.0, $size - $d, $d, $d, 90, 90)
|
$path.AddArc(0.0, $size - $d, $d, $d, 90, 90)
|
||||||
$path.CloseFigure()
|
$path.CloseFigure()
|
||||||
$brush = New-Object System.Drawing.SolidBrush($window)
|
$brush = New-Object System.Drawing.SolidBrush($accent)
|
||||||
$g.FillPath($brush, $path)
|
$g.FillPath($brush, $path)
|
||||||
|
|
||||||
# 108-viewport units to pixels, with the outer 18 dropped on each edge.
|
# 108-viewport units to pixels, with the outer 18 dropped on each edge.
|
||||||
@@ -51,30 +55,21 @@ function New-MarkPng([int]$size)
|
|||||||
function P([double]$x, [double]$y) { New-Object System.Drawing.PointF((($x - 18.0) * $scale), (($y - 18.0) * $scale)) }
|
function P([double]$x, [double]$y) { New-Object System.Drawing.PointF((($x - 18.0) * $scale), (($y - 18.0) * $scale)) }
|
||||||
|
|
||||||
# A stroke thinner than a pixel renders as a grey suggestion of itself, which at 16px is the
|
# A stroke thinner than a pixel renders as a grey suggestion of itself, which at 16px is the
|
||||||
# difference between a mark and a smudge. The phone's file already bumps these widths for the
|
# difference between a mark and a smudge. The phone's file already bumps this width for the
|
||||||
# same reason at 48dp; the floor is that argument carried down to the sizes Windows asks for.
|
# same reason at 48dp; the floor is that argument carried down to the sizes Windows asks for.
|
||||||
function Pen([double]$units)
|
$pen = New-Object System.Drawing.Pen($ink, [float][Math]::Max(5.4 * $scale, 1.0))
|
||||||
{
|
|
||||||
$pen = New-Object System.Drawing.Pen($accent, [float][Math]::Max($units * $scale, 1.0))
|
|
||||||
$pen.StartCap = [System.Drawing.Drawing2D.LineCap]::Round
|
$pen.StartCap = [System.Drawing.Drawing2D.LineCap]::Round
|
||||||
$pen.EndCap = [System.Drawing.Drawing2D.LineCap]::Round
|
$pen.EndCap = [System.Drawing.Drawing2D.LineCap]::Round
|
||||||
$pen.LineJoin = [System.Drawing.Drawing2D.LineJoin]::Round
|
$pen.LineJoin = [System.Drawing.Drawing2D.LineJoin]::Round
|
||||||
return $pen
|
|
||||||
}
|
|
||||||
|
|
||||||
# The box: 42 across, centred, square-cornered as the Border in the app is.
|
|
||||||
$box = Pen 2.2
|
|
||||||
$g.DrawPolygon($box, @((P 33 33), (P 75 33), (P 75 75), (P 33 75)))
|
|
||||||
|
|
||||||
# The chevron of >_ and the underscore on the baseline it bottoms out at.
|
# The chevron of >_ and the underscore on the baseline it bottoms out at.
|
||||||
$ink = Pen 2.8
|
$g.DrawLines($pen, @((P 36.06 43.33), (P 49.91 53.57), (P 36.06 63.8)))
|
||||||
$g.DrawLines($ink, @((P 44.8 48.75), (P 51.9 54), (P 44.8 59.25)))
|
$g.DrawLine($pen, (P 54 64.68), (P 71.94 64.68))
|
||||||
$g.DrawLine($ink, (P 54 59.7), (P 63.2 59.7))
|
|
||||||
|
|
||||||
$stream = New-Object System.IO.MemoryStream
|
$stream = New-Object System.IO.MemoryStream
|
||||||
$bitmap.Save($stream, [System.Drawing.Imaging.ImageFormat]::Png)
|
$bitmap.Save($stream, [System.Drawing.Imaging.ImageFormat]::Png)
|
||||||
|
|
||||||
$box.Dispose(); $ink.Dispose(); $brush.Dispose(); $path.Dispose(); $g.Dispose(); $bitmap.Dispose()
|
$pen.Dispose(); $brush.Dispose(); $path.Dispose(); $g.Dispose(); $bitmap.Dispose()
|
||||||
return $stream.ToArray()
|
return $stream.ToArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.6 KiB |
Reference in New Issue
Block a user