feat: klasor tabanli galeri, brightness efekti (Ctrl+Shift+sag tik), .deb guncellendi

This commit is contained in:
Alhan
2026-08-03 08:26:31 +03:00
parent 56ab4b5495
commit d4c243b445
9 changed files with 249 additions and 37 deletions

View File

@@ -0,0 +1,65 @@
# Galeri: Klasör Tabanlı Gezinme — Rapor ve Plan
Tarih: 2026-08-03
Durum: Uygulandı (2026-08-03)
## 1. Mevcut Sorunun Analizi
### RAM şişmesi — `lib/services/image_manager.dart`
- `addImages()` her eklenen yol için `precacheImage(FileImage(...))` çağırıyor (satır 33-35).
- Sonuç: toplu sürüklemede tüm resimler tam çözünürlükte decode edilip ImageCache'e yazılıyor.
- Örnek: 12MP JPEG dekode ≈ 48MB RGBA; 30 resim ≈ 1.4GB.
- Decode UI thread'inde yapılıyor → pencere donması, "çok pencere açmış gibi" hissi.
- `configureCache()` tavanı: 1000 görsel / 1GB (satır 62-65).
### Sağ tık efektlerinde çökme — `lib/widgets/image_canvas.dart`
- Her pointer move'da `setState``ColorFiltered` tüm görseli yeniden boyuyor (satır 224-240).
- Bellek zaten yüksekken + VM'de yazılımsal render → çökme en çok burada görülüyor.
- Kök neden RAM şişmesi; o çözülünce bu senaryo da hafifler.
## 2. Alınan Kararlar (kullanıcı onayı)
1. **Precache tamamen kaldırılacak** — hiçbir resim önceden decode edilmeyecek.
2. Görüntüleme anında decode: sıradaki resme geçişte yüklenene kadar beklenir.
3. **RAM kısıtlaması yok** — cache limitlerine dokunulmayacak, daraltılmayacak.
4. Önceki resim cache'ten düşebilir (zorunlu tutma yok). Precache olmadığı için
bellekte aynı anda yalnızca açık olan resim(ler) durur; kabarık galeri listesi
sorun yaratmaz.
## 3. Yeni Özellik — Klasör Tabanlı Galeri
Amaç: resimleri topluca seçip sürükleyerek galeri kurmak yerine, açılan herhangi
bir resmin bulunduğu dizin otomatik galeri olsun.
Davranış:
- Bir resim açıldığında (çift tık, CLI argümanı, sürükle-bırak) bulunduğu dizin taranır.
- Dizindeki desteklenen imaj dosyaları (png/jpg/jpeg/jfif/jpe/webp/bmp/gif/wbmp)
galeri listesi olarak set edilir.
-ılan resim listedeki konumunu bulur ve o an gösterilir.
- Ctrl+Tab / Ctrl+Shift+Tab ile klasör içinde ileri-geri gezilir.
- Mevcut pencere başına singleton yapısı korunur — her pencere ayrı process,
her biri kendi klasör galerisini kurar.
### Sıralama
- Dosya yöneticisinin (Thunar/PCManFM/Nautilus) klasör sort'u OS seviyesinde
okunamaz — uygulama içi ayardır, dosya sisteminde saklanmaz. Bu seçenek pratikte yok.
- Bu yüzden **tarihe göre** sıralanacak (dosyanın değiştirilme zamanı).
- Yön: **en yeni önce, en eski sonra** (azalan).
## 4. Uygulama (uygulandı)
- `lib/services/image_manager.dart` — precache döngüsü ve `buildContext` kaldırıldı.
`addImages` yerine `setGalleryFromPaths(paths)` geldi: ilk geçerli resmin klasörünü
tarar, desteklenenleri filtreler, değiştirilme zamanına göre en yeni önce sıralar,
ılan resmi o anki konum yapar. (Aynı zaman damgasında dosya adına göre sabit sıra)
- `lib/services/file_handler.dart``addImages` çağrıları `setGalleryFromPaths` oldu
(Ctrl+O ve sürükle-bırak aynı akıştan geçiyor).
- `lib/screens/viewer_screen.dart``buildContext` ataması kaldırıldı (precache yok).
- RAM kısıtlaması eklenmedi — `configureCache` aynen duruyor.
## 5. Açık Sorular
Çözüldü:
1. ~~Tarih sıralama yönü~~**en yeni önce, en eski sonra**
2. ~~Pencereye birden fazla resim sürüklenirse~~**sürüklenen resmin klasörüne geçilir**
(galeri açıkken yeni resim gelirse de aynı: o resmin klasörü yeni galeri olur)

View File

@@ -2,6 +2,8 @@
| Tarih | Dosya | Konu |
|---|---|---|
| 2026-08-03 | [rapor-brightness.md](rapor-brightness.md) | **Rapor** — brightness efekti (Ctrl+Shift+sağ tık) + 4x5 matris birleştirme |
| 2026-08-03 | [galeri-klasor-tabanli.md](galeri-klasor-tabanli.md) | **Rapor** — klasör tabanlı galeri + precache/RAM kararı |
| 2026-08-03 | [session-2026-08-03.md](session-2026-08-03.md) | **Session özeti** — jfif/jpe/wbmp, pencere cascade, konum kaydı düzeltmesi |
| 2026-08-03 | [format-destegi-ek-formatlar.md](format-destegi-ek-formatlar.md) | **Plan** — jfif/jpe/wbmp desteği (TIFF vazgeçildi) |
| 2026-08-03 | [pencere-cascade-yerlesim.md](pencere-cascade-yerlesim.md) | **Plan** — yeni pencereyi yan yana / alt satıra açma (screen_retriever) |
@@ -9,3 +11,9 @@
| 2026-07-27 | [session-2026-07-27.md](session-2026-07-27.md) | **Session özeti** — rotate aktif, StartupWMClass ile taskbar gruplama |
| 2026-07-27 | [image-canvas-interactions.md](image-canvas-interactions.md) | Detaylı analiz: contrast, saturation, rotate implementasyon planı |
| önceki | [zoom-clamp-mekanizmasi.md](zoom-clamp-mekanizmasi.md) | Zoom clamp mekanizması (letterbox-aware) |
## Geliştirme Akışı — Otomatik Build ve Kurulum
Projede değişiklik yapıldıktan sonra otomatik yapılır (ayrıca istenmez):
1. Debug build: `flutter build linux --debug`
2. Sisteme kurulum: `./install.sh` (debug bundle tercih edilir → `~/.local/lib/imajviewer/`)

62
docs/rapor-brightness.md Normal file
View File

@@ -0,0 +1,62 @@
# Rapor: Brightness Efekti + Sağ Tık Etkileşim Düzeni
Tarih: 2026-08-03
Durum: Rapor — uygulama için onay bekleniyor
## 1. Gönderilen Araştırmanın Özeti
- `ColorMatrixHelper`: Rec.709 luma katsayıları (0.2126 / 0.7152 / 0.0722) — projedekiyle aynı.
- Üç ayrı 4x5 renk matrisi:
- **Brightness:** RGB'ye offset ekler (`b` → -255..255)
- **Contrast:** `c` ile çarpar + `128*(1-c)` offset (0..2 arası, 1.0 orijinal)
- **Saturation:** Rec.709 ağırlıklı karışım (0..2 arası, 1.0 orijinal)
- Birleştirme: `M_final = M_contrast * M_brightness * M_saturation` — genel 4x5 matris
çarpımı; uygulama sırası saturation → brightness → contrast.
- Uygulama: `ColorFiltered` + `ColorFilter.matrix` ile GPU shader'ı — projedekiyle aynı mekanizma.
- Örnek widget (`ImageAdjusterWidget`) **slider tabanlı**; bizim uygulama jest tabanlı
olduğu için bu kısım direkt uygulanmayacak. Asıl değer matris hesabında.
## 2. Projedeki Mevcut Durum — `lib/widgets/image_canvas.dart`
- State: `_contrast` (1.0), `_saturation` (1.0) — brightness yok.
- `_buildCombinedFilter()`: saturation × contrast tek matriste elle birleştiriliyor
(contrast offset: `t = (1-c)/2` → 255 ölçeğinde 127.5*(1-c)).
- Cache: `_cachedFilter` + `_cachedSat` / `_cachedCon`.
- Etkileşim: sağ tık = contrast, Ctrl+sağ tık = saturation, Shift+sağ tık = rotate,
sağ çift tık = reset (tüm efektler).
- Modifier takibi: `_onHardwareKey` yalnızca ctrl ve shift'i izliyor.
## 3. Karşılaştırma — Araştırma vs Mevcut Kod
| Konu | Mevcut | Araştırma | Fark |
|---|---|---|---|
| Saturation matrisi | Rec.709, aynı formül | Rec.709, aynı formül | Matematik birebir aynı |
| Contrast offset | 127.5*(1-c) | 128*(1-c) | ~%0.4, görsel fark yok |
| Brightness | yok | `b` offset matrisi | **Eklenecek** |
| Birleştirme | elle 2 matris | genel 4x5 çarpım | 3 efekt için genel çarpım daha temiz |
| Arayüz | jest (sağ tık + sürükle) | slider | Widget değil, matris katmanı alınacak |
## 4. Uygulama Planı
1. `_brightness` state ekle (varsayılan 0.0, aralık -100..100).
2. `_onPointerDown`: öncelik sırası**Ctrl+Shift → brightness**, Ctrl → saturation,
Shift → rotate, yoksa contrast. (Başlangıçta Alt denenmişti; XFCE Alt+klik'i
pencere hareketine kaptığı için **Ctrl+Shift**'e geçildi.)
3. `_onPointerMove`: brightness modunda `_brightness = _startBrightness + dy * 0.5`
(clamp -100..100; hassasiyet açık soru).
4. `_buildCombinedFilter`: araştırmadaki 4x5 çarpım mantığıyla 3 efekt birleştir
(saturation → brightness → contrast); cache anahtarına `_brightness` ekle.
5. Reset (sağ çift tık), `_resetView`, `_toggleFillFit`: brightness 0'a döner.
6. `hasFilter` koşuluna `_brightness != 0` eklenir (ColorFiltered yalnızca gerektiğinde).
## 5. Dikkat Edilecekler
- **Linux/XFCE:** Alt+klik WM tarafından pencere hareketine kaptırıldığı için
brightness **Ctrl+Shift+sağ tık**'a alındı (Alt kaldırıldı).
- **Uygulama sırası:** saturation → brightness → contrast sabit kalacak; farklı sıra farklı sonuç verir.
- Reset davranışı brightness'i de kapsar.
## 6. Açık Sorular
1. Brightness hassasiyeti: `dy * 0.5`, aralık -100..100 uygun mu?
2. Rotate Shift+sağ tık'ta kalıyor (değişiklik yok) — onay?