Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,10 @@ Cosa fa e come si usa: `README.md` (corto, per l'utente) e `docs/GUIDA.md` (comp
- **La home** (`ui/src/app/home.ts`): le sei strade (il selettore si apre già filtrato: comando `scegli` con `categoria`), gli ultimi
convertiti (`Storico.cs`, `storico.json`, solo l'app lo scrive: la coda lo chiama tramite `Coda.QuandoFatto`) e come sta il PC.
- **Suoni** spenti di partenza: la proprietà si chiama `SuoniAccesi` (nome nuovo apposta, come `CestinoDaSolo`).
- **Icone e miniature** (dalla 2.2.8): `Icone.cs` scrive il .ico del tipo (16…256). Fino a 24 pixel è `Glifi.Mattonella`
(sagoma piena: a 16 il foglio piegato era una macchia); da 32 in su il foglio, col tratto in pixel e non
`1.45/scala` (quel conto a 32 pixel gonfiava il segno). La miniatura audio (`Multimedia.Audio`) mette la copertina
a sinistra — `Media.Copertina`, dentro il file o `cover.jpg` / `folder.jpg`, in silenzio — e l'onda vera a destra
(`Onde.Barre`). Sotto i 48 la copertina sta sopra e l'onda è una striscia; a 16–24 senza copertina si torna null e
resta il .ico. Il nome del file .ico porta la versione: al cambio si buttano i vecchi. Cosa non si fa ora (scheda
del file, tagli piccoli, niente montaggio: quello è DaProd Editor Video) sta in `docs/ROADMAP.md`.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Le novità di ogni versione, dette come stanno. La più nuova sta in alto.

## 2.2.8 — 9 novembre 2026

- **Le icone dei file sono rifatte, e quelle piccole si leggono.** A 16, 20 e 24 pixel non c'è più il foglio piegato (diventava una macchia): c'è una mattonella tonda, viola notte, col bordo del colore del tipo e una sagoma piena. Video, musica, foto, PDF, documenti, fogli, presentazioni, codice, sottotitoli, archivi, caratteri e modelli hanno ognuno il suo segno. Dalle 32 pixel in su resta il foglio, col disegnino più nitido.
- **La musica in Esplora file mostra la copertina e l'onda vera.** A sinistra la copertina del brano (quella dentro il file, oppure `cover.jpg` / `folder.jpg` nella cartella), a destra la forma d'onda di quel brano, magenta e oro. Senza copertina c'è un disco. Sotto, il formato e la durata. Nelle viste piccole la copertina riempie l'icona e l'onda diventa una striscia; a 16 pixel, se il brano non ha copertina, resta la mattonella del tipo, che è più chiara.
- **In arrivo**, senza fretta e senza diventare un programma di montaggio: la scheda del file (titolo, artista, copertina, e le informazioni che si possono correggere) e i tagli piccoli. Il montaggio vero resta [DaProd Editor Video](https://github.com/cammo22/DaProdEditorVideo). I dettagli sono in `docs/ROADMAP.md`.

## 2.2.7 — 4 novembre 2026

- **La colonna di mezzo non si rompe più con l'anteprima aperta.** Si regolava sulla larghezza della finestra, non sulla sua: con
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!-- La versione sta solo qui. Si alza di 0.0.1 e si scrive la voce nel CHANGELOG:
la CI la legge da questo file e pubblica la release da sola. -->
<PropertyGroup>
<Version>2.2.7</Version>
<Version>2.2.8</Version>
<Authors>DaProd</Authors>
<Company>DaProdProduzioni</Company>
<Product>DaP Convertitore</Product>
Expand Down
16 changes: 9 additions & 7 deletions docs/GUIDA.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,15 @@ Sempre: **Pag ↑ / Pag ↓** il file prima e dopo, **F11** schermo intero, **I*
finestra e lo apre.

**Icone e anteprime in Esplora file.** Ogni tipo ha la sua icona (magenta i video, verde la musica, ciano le foto,
rossa il PDF, oro i modelli 3D…) e nelle viste a icone grandi si vede il contenuto vero: la **foto**, il
**fotogramma del video** con la pellicola, il tasto play e la durata, la **forma d'onda** della musica (come i vocali
di WhatsApp, con la durata), il **modello 3D** su uno sfondo da studio, la prima pagina del **PDF** e dei documenti,
il testo e il codice colorato, le tabelle, i caratteri («Aa» nel carattere stesso), il contenuto dei file ZIP. Dove
Windows ne ha già una buona (Word con Office, per dire) resta la sua. Le anteprime vengono disegnate dall'exe
(`--miniatura`), lanciato da una piccola DLL (`menu\DaPMiniature.cpp`) registrata come «provider di miniature»; per
guardarne una a occhio: `DaPConvertitore.exe --miniatura-png file 256 uscita.png`.
rossa il PDF, oro i modelli 3D…). Nelle viste piccole è una mattonella col segno del tipo; in quelle grandi è un
foglio col bordo piegato. Accanto si vede il contenuto vero: la **foto**, il **fotogramma del video** con la
pellicola, il tasto play e la durata, la **musica** con la copertina a sinistra e la forma d'onda di quel brano a
destra (formato e durata sotto; senza copertina c'è un disco), il **modello 3D** su uno sfondo da studio, la prima
pagina del **PDF** e dei documenti, il testo e il codice colorato, le tabelle, i caratteri («Aa» nel carattere
stesso), il contenuto dei file ZIP. Dove Windows ne ha già una buona (Word con Office, per dire) resta la sua. Le
anteprime vengono disegnate dall'exe (`--miniatura`), lanciato da una piccola DLL (`menu\DaPMiniature.cpp`)
registrata come «provider di miniature»; per guardarne una a occhio:
`DaPConvertitore.exe --miniatura-png file 256 uscita.png`.

**Al posto di Foto e Lettore multimediale.** Il lettore si mette in *Apri con* di Windows per tutti i tipi che
conosce, senza prendersi niente da solo. Per aprire col doppio clic: *Impostazioni → App predefinite* nel
Expand Down
34 changes: 34 additions & 0 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Più avanti

Cose che ha senso fare, senza trasformare DaP Convertitore in un altro programma. Il montaggio vero sta in
[DaProd Editor Video](https://github.com/cammo22/DaProdEditorVideo): timeline, transizioni, colore, pagina Finale.
Qui restano i gesti piccoli, quelli che fai sul file che stai già guardando.

## La scheda del file

Nel lettore, **I** mostra già le proprietà. Il passo dopo è poterle **correggere e scriverle nel file**, con la
stessa bozza che già usano la rotazione e il ritocco (si scrive accanto, poi si sostituisce; se qualcosa va storto
l'originale resta).

- **Musica**: titolo, artista, album, anno, numero di traccia, e la copertina (quella dentro il file, o un'immagine
scelta). I formati che la tengono sono MP3, M4A e FLAC; gli altri lo dicono.
- **Foto**: data dello scatto, descrizione, autore, dove il formato tiene i dati (JPG e TIFF). L'orientamento si
cambia già.
- **Video**: titolo e commento, sui contenitori che li tengono (MP4, MOV, MKV), senza ricodificare.

Niente campi inventati e niente di quello che il formato non sa conservare.

## Tagli piccoli

Nel lettore video **Z** e **X** segnano già un pezzo e lo salvano accanto, senza perdite. Da Editor Video si prende
solo l'idea dei gesti corti (lì **1** taglia, **2** toglie, **Q** e **W** tengono la testa o la coda), non il banco.

- Tenere solo la testa, solo la coda, o il pezzo fra due punti. Il file nuovo si chiama «(tagliato)» e l'originale
non si tocca.
- Lo stesso su un **brano**: un pezzo solo, accanto, senza ricodificare dove il formato lo permette e ricodificando
dove non si può (MP3).
- **Unire** due o tre file uno dopo l'altro, stesso tipo (due video, o due brani), senza transizioni e senza tracce
in più. Il risultato sta accanto.

Niente timeline a più piste, niente dissolvenze, niente cubo, niente pagina del colore. Per quello si apre
DaProd Editor Video.
5 changes: 3 additions & 2 deletions src/DaPConvertitore.Motore/Lettore/Media.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,16 @@ public static async Task<SchedaMedia> Leggi(Strumenti s, string percorso)
}

/// <summary>La copertina: quella dentro il file, o cover.jpg / folder.jpg nella cartella. JPEG piccolo.</summary>
public static async Task<byte[]?> Copertina(Strumenti s, string percorso, bool dentro)
public static async Task<byte[]?> Copertina(Strumenti s, string percorso, bool dentro, bool silenzioso = false, int lato = 800)
{
if (dentro)
{
var jpg = Path.Combine(Strumenti.CartellaTemporanea, $"copertina-{Guid.NewGuid():N}.jpg");
try
{
var scala = $"scale='min({Math.Clamp(lato, 32, 800)},iw)':-2";
var r = await Processi.Esegui(s.Ffmpeg, ["-hide_banner", "-loglevel", "error", "-y", "-i", percorso, "-map", "0:v:0", "-frames:v", "1",
"-vf", "scale='min(800,iw)':-2", "-q:v", "3", "-update", "1", jpg], CancellationToken.None, tieniUscita: false);
"-vf", scala, "-q:v", "3", "-update", "1", jpg], CancellationToken.None, tieniUscita: false, silenzioso: silenzioso);
if (r.Codice == 0 && File.Exists(jpg)) return await File.ReadAllBytesAsync(jpg);
}
finally { try { File.Delete(jpg); } catch { } }
Expand Down
1 change: 1 addition & 0 deletions src/DaPConvertitore/Miniature/Documenti.cs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ public static Quadro Generica(string gruppo, string estensione, int L)
{
var tinta = Tavolozza.Tinta(gruppo);
var est = estensione.TrimStart('.').ToUpperInvariant();
if (L <= 32) return Tela.Fai(L, L, dc => Glifi.Mattonella(dc, gruppo, new Rect(0, 0, L, L)));
return Tela.Fai(L, L, dc =>
{
var r = new Rect(0, 0, L, L);
Expand Down
160 changes: 159 additions & 1 deletion src/DaPConvertitore/Miniature/Glifi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,174 @@ static Geometry Forma(string gruppo)

/// <summary>
/// Disegna la figurina del gruppo dentro <paramref name="dove"/> (un quadrato). <paramref name="spessore"/> è in
/// unità della griglia di 24: 1.8 è quello dell'interfaccia.
/// unità della griglia di 24: 1.8 è quello dell'interfaccia. Sotto i 20 pixel il tratto diventa un blob: lì si
/// usa la sagoma piena, fatta apposta per le misure piccole.
/// </summary>
public static void Disegna(DrawingContext dc, string gruppo, Rect dove, Color colore, double spessore = 1.8, double alfa = 1)
{
var lato = Math.Min(dove.Width, dove.Height);
if (lato < 20)
{
Pieno(dc, gruppo, dove, colore, alfa);
return;
}
var s = lato / 24.0;
dc.PushTransform(new TranslateTransform(dove.X + (dove.Width - lato) / 2, dove.Y + (dove.Height - lato) / 2));
dc.PushTransform(new ScaleTransform(s, s));
dc.DrawGeometry(null, Tavolozza.Penna(colore, spessore, alfa), Forma(gruppo));
dc.Pop();
dc.Pop();
}

/// <summary>
/// La mattonella delle misure piccole (16, 20, 24): un quadrato tondo, viola notte, col bordo del tipo e la
/// sagoma piena in mezzo. A 16 pixel una pagina piegata non si legge.
/// </summary>
public static void Mattonella(DrawingContext dc, string gruppo, Rect area)
{
var tinta = Tavolozza.Tinta(gruppo);
// a 16 pixel il bordo grosso e il segno piccolo si mangiavano il disegno: bordo da un pixel, segno grande
double m = area.Width <= 16 ? 0.35 : Math.Max(0.5, area.Width * 0.045);
double bordo = area.Width <= 16 ? 1 : Math.Max(1, area.Width * 0.065);
var r = new Rect(area.X + m + bordo / 2, area.Y + m + bordo / 2, Math.Max(1, area.Width - 2 * m - bordo), Math.Max(1, area.Height - 2 * m - bordo));
var fondo = Tavolozza.P(Tavolozza.C("#160e2c"));
dc.DrawRoundedRectangle(fondo, new Pen(Tavolozza.P(tinta), bordo) { LineJoin = PenLineJoin.Round }, r, r.Width * 0.22, r.Width * 0.22);
var lato = r.Width * (area.Width <= 20 ? 0.78 : 0.62);
Pieno(dc, gruppo, new Rect(r.X + (r.Width - lato) / 2, r.Y + (r.Height - lato) / 2, lato, lato), tinta);
}

/// <summary>La sagoma piena del tipo, su una griglia di 24. Pochi pezzi grossi: si legge anche a 16 pixel.</summary>
public static void Pieno(DrawingContext dc, string gruppo, Rect dove, Color colore, double alfa = 1)
{
var lato = Math.Min(dove.Width, dove.Height);
var ox = dove.X + (dove.Width - lato) / 2;
var oy = dove.Y + (dove.Height - lato) / 2;
double X(double v) => ox + v / 24.0 * lato;
double Y(double v) => oy + v / 24.0 * lato;
double S(double v) => v / 24.0 * lato;
var b = Tavolozza.P(colore, alfa);

void Rett(double x, double y, double w, double h)
{
var rr = Math.Min(S(w), S(h)) * 0.42;
dc.DrawRoundedRectangle(b, null, new Rect(X(x), Y(y), S(w), S(h)), rr, rr);
}

void Poli(params (double x, double y)[] p)
{
var g = new StreamGeometry();
using (var c = g.Open())
{
c.BeginFigure(new Point(X(p[0].x), Y(p[0].y)), true, true);
for (var i = 1; i < p.Length; i++) c.LineTo(new Point(X(p[i].x), Y(p[i].y)), true, true);
}
g.Freeze();
dc.DrawGeometry(b, null, g);
}

// sotto i 14 pixel la cinepresa, le parentesi e il diamante diventano una macchia: un segno solo, grosso
if (lato < 14)
{
switch (gruppo)
{
case "Video":
Poli((4.2, 3.2), (4.2, 20.8), (21, 12));
return;
case "Codice":
Poli((1.4, 5.2), (9.2, 12), (1.4, 18.8));
Poli((22.6, 5.2), (14.8, 12), (22.6, 18.8));
return;
case "Immagine":
dc.DrawEllipse(b, null, new Point(X(7.2), Y(6.4)), S(2.6), S(2.6));
Poli((2, 19.6), (12, 8.4), (22, 19.6));
return;
case "Modello":
Poli((12, 1.6), (22.2, 20.4), (1.8, 20.4));
return;
}
}

switch (gruppo)
{
case "Video":
Rett(1.6, 6.4, 12.6, 11.2);
Poli((14.6, 8.4), (21.8, 12), (14.6, 15.6));
break;
case "Audio":
Rett(3.4, 11, 4.2, 8.4);
Rett(9.9, 4.8, 4.2, 14.6);
Rett(16.4, 8, 4.2, 11.4);
break;
case "Immagine":
dc.DrawEllipse(b, null, new Point(X(8.2), Y(8)), S(2.5), S(2.5));
Poli((2.4, 19.4), (10.2, 11.2), (15.2, 16.2), (18.2, 13.4), (21.8, 19.4));
break;
case "Pdf":
Poli((5.5, 2), (13.2, 2), (19.2, 8), (19.2, 22), (5.5, 22));
var piega = new StreamGeometry();
using (var c = piega.Open())
{
c.BeginFigure(new Point(X(13.2), Y(2)), true, true);
c.LineTo(new Point(X(19.2), Y(8)), true, true);
c.LineTo(new Point(X(13.2), Y(8)), true, true);
}
piega.Freeze();
dc.DrawGeometry(Tavolozza.P(Colors.White, alfa * 0.92), null, piega);
break;
case "Documento":
Rett(4, 4.2, 16, 2.5);
Rett(4, 9.2, 16, 2.5);
Rett(4, 14.2, 16, 2.5);
Rett(4, 19.2, 10, 2.5);
break;
case "Presentazione":
Rett(2, 3.6, 20, 12.2);
Rett(10.4, 16.2, 3.2, 2.6);
Rett(6.2, 18.8, 11.6, 2.2);
break;
case "Tabella":
Rett(2.6, 2.6, 8.2, 8.2);
Rett(13.2, 2.6, 8.2, 8.2);
Rett(2.6, 13.2, 8.2, 8.2);
Rett(13.2, 13.2, 8.2, 8.2);
break;
case "Codice":
var penna = new Pen(b, Math.Max(1.15, S(2.6))) { StartLineCap = PenLineCap.Round, EndLineCap = PenLineCap.Round, LineJoin = PenLineJoin.Round };
penna.Freeze();
dc.DrawLine(penna, new Point(X(9.4), Y(5.2)), new Point(X(3.2), Y(12)));
dc.DrawLine(penna, new Point(X(3.2), Y(12)), new Point(X(9.4), Y(18.8)));
dc.DrawLine(penna, new Point(X(14.6), Y(5.2)), new Point(X(20.8), Y(12)));
dc.DrawLine(penna, new Point(X(20.8), Y(12)), new Point(X(14.6), Y(18.8)));
break;
case "Sottotitoli":
var cornice = new Pen(b, Math.Max(1.1, S(1.9))) { LineJoin = PenLineJoin.Round };
cornice.Freeze();
dc.DrawRoundedRectangle(null, cornice, new Rect(X(2.2), Y(5.4), S(19.6), S(13.2)), S(2.2), S(2.2));
Rett(4.8, 10.4, 5.4, 2.2);
Rett(12, 10.4, 6.6, 2.2);
break;
case "Archivio":
Rett(6.6, 2.4, 10.8, 3.3);
Rett(6.6, 7.4, 10.8, 3.3);
Rett(6.6, 12.4, 10.8, 3.3);
Rett(9, 17.2, 6, 4.4);
break;
case "Font":
var lettera = Scritte.Testo("A", Scritte.Titolo, lato * 0.82, b);
dc.DrawText(lettera, new Point(ox + (lato - lettera.Width) / 2, oy + (lato - lettera.Height) / 2 - lato * 0.04));
break;
case "Modello":
Poli((12, 1.8), (21.6, 12), (12, 22.2), (2.4, 12));
break;
case "Testo":
Rett(3.2, 4, 17.6, 2.15);
Rett(3.2, 8.3, 17.6, 2.15);
Rett(3.2, 12.6, 14, 2.15);
Rett(3.2, 16.9, 11, 2.15);
break;
default:
Poli((6, 2), (14, 2), (19.5, 7.5), (19.5, 22), (6, 22));
break;
}
}
}
Loading
Loading