Uygulama: Kiosk Modu (Tam Ekran)

Pardus ETAP (Etkileşimli Tahta) projesi için Kiosk Modu (Tam Ekran ve Çerçevesiz) çok önemlidir. Öğrencilerin ders sırasında uygulamayı yanlışlıkla kapatmasını veya başka pencerelere geçmesini engellemek için bu yöntemi kullanırız.

Bunun için Flutter'ın popüler paketi olan window_manager'ı kullanacağız.

İşte adım adım Pardus uygulamanızı bir ETAP arayüzüne dönüştürme rehberi:


Bu adımda uygulamamızın pencere kenarlıklarını (Kapat, Küçült butonlarını) kaldıracak ve ekranı tamamen kaplamasını sağlayacağız.

⚠️ Önemli Uyarı: Uygulamayı tam ekran yaptığımızda "Kapat (X)" butonu da kaybolacağı için, uygulamadan çıkış yapabilmek adına kodumuza mutlaka bir "Çıkış Butonu" eklemeliyiz. Yoksa uygulamayı kapatmak için fişi çekmek zorunda kalabiliriz! :)

1. Adım: Paketi Ekleme

Terminali proje klasöründe açın ve pencere yönetimi paketini ekleyin:

Bash:
flutter pub add window_manager

2. Adım: main.dart Ayarları

Şimdi lib/main.dart dosyamızı düzenleyerek uygulama başlarken tam ekran olmasını sağlayacağız.

Mevcut main() fonksiyonunu ve AnaSayfa kodlarını şu şekilde güncelleyin:

Dart:
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:window_manager/window_manager.dart'; // 1. YENİLİK: Paket eklendi

void main() async {
  // 2. YENİLİK: Widget ve Window Manager başlatma ayarları
  WidgetsFlutterBinding.ensureInitialized();
  await windowManager.ensureInitialized();

  WindowOptions windowOptions = const WindowOptions(
    size: Size(800, 600),
    center: true,
    backgroundColor: Colors.transparent,
    skipTaskbar: false,
    titleBarStyle: TitleBarStyle.hidden, // Pencere kenarlıklarını (X butonunu) gizler
  );

  await windowManager.waitUntilReadyToShow(windowOptions, () async {
    await windowManager.show();
    await windowManager.focus();
    await windowManager.setFullScreen(true); // TAM EKRAN MODU
  });

  runApp(const PardusUygulamasi());
}

// ... PardusUygulamasi class'ı aynı kalabilir ...
class PardusUygulamasi extends StatelessWidget {
  const PardusUygulamasi({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pardus ETAP Kiosk',
      debugShowCheckedModeBanner: false, // Sağ üstteki "Debug" bandını kaldırır
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blueAccent),
        useMaterial3: true,
      ),
      home: const AnaSayfa(),
    );
  }
}

class AnaSayfa extends StatefulWidget {
  const AnaSayfa({super.key});

  @override
  State<AnaSayfa> createState() => _AnaSayfaState();
}

class _AnaSayfaState extends State<AnaSayfa> {
  // Eski değişkenlerimiz duruyor
  bool _logoGorunurMu = false;
  String _ipAdresi = "IP Adresi Sorgulanmadı";

  void _logoDurumuDegistir() {
    setState(() {
      _logoGorunurMu = !_logoGorunurMu;
    });
  }

  Future<void> _ipSorgula() async {
    try {
      final sonuc = await Process.run('hostname', ['-I']);
      setState(() {
        _ipAdresi = "IP: ${sonuc.stdout.toString().trim()}";
      });
    } catch (e) {
      setState(() {
        _ipAdresi = "Hata: $e";
      });
    }
  }

  // 3. YENİLİK: Uygulamadan Çıkış Fonksiyonu
  void _cikisYap() {
    exit(0); // Uygulamayı tamamen kapatır
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // AppBar'ı kaldırdık çünkü tam ekran kiosk modunda genelde üst bar olmaz.
      // Onun yerine modern bir arkaplan rengi verelim.
      backgroundColor: Colors.white, 
      
      // Sağ üst köşeye güvenli bir çıkış butonu ekleyelim
      floatingActionButton: FloatingActionButton(
        onPressed: _cikisYap,
        backgroundColor: Colors.red,
        child: const Icon(Icons.power_settings_new, color: Colors.white),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.endTop,

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            if (_logoGorunurMu)
              Container(
                margin: const EdgeInsets.only(bottom: 20),
                width: 300, // ETAP büyük ekran olduğu için logoyu büyüttük
                child: Image.asset('assets/pardus_logo.png'),
              )
            else
              const Icon(Icons.desktop_mac, size: 150, color: Colors.grey),

            const SizedBox(height: 30),

            Container(
              padding: const EdgeInsets.all(20),
              decoration: BoxDecoration(
                color: Colors.blue[50],
                borderRadius: BorderRadius.circular(15),
                border: Border.all(color: Colors.blueAccent)
              ),
              child: Text(
                _ipAdresi,
                style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold), // Yazıları büyüttük
              ),
            ),

            const SizedBox(height: 50),

            // Butonları Yan Yana ve Daha Büyük Yapalım
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton.icon(
                  onPressed: _logoDurumuDegistir,
                  icon: const Icon(Icons.image, size: 30),
                  label: Text(_logoGorunurMu ? "Logoyu Gizle" : "Logoyu Göster", style: const TextStyle(fontSize: 20)),
                  style: ElevatedButton.styleFrom(
                    padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20),
                  ),
                ),
                const SizedBox(width: 30),
                ElevatedButton.icon(
                  onPressed: _ipSorgula,
                  icon: const Icon(Icons.wifi, size: 30),
                  label: const Text("IP Sorgula", style: TextStyle(fontSize: 20)),
                  style: ElevatedButton.styleFrom(
                    padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20),
                    backgroundColor: Colors.blueAccent,
                    foregroundColor: Colors.white,
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

3. Adım: C++ Ayarı (Linux İçin Gerekli)

window_manager paketinin Linux'ta düzgün çalışabilmesi için linux/runner/my_application.cc dosyasında çok küçük bir değişiklik yapmamız gerekebilir (genelde son sürümlerde otomatik olsa da garantiye alalım).

Ancak Pardus üzerinde çoğu zaman yukarıdaki Dart kodu tek başına yeterli olur. Önce yukarıdaki kodu çalıştırıp deneyelim.

Terminalden çalıştırın:

Bash:
flutter run -d linux

Sonuç:

  • Uygulama açılır açılmaz tüm ekranı kaplayacak.

  • Üstteki pencere çubuğu (başlık, kapat butonu vb.) olmayacak.

  • Sağ üst köşedeki Kırmızı Güç Butonu ile uygulamadan çıkabileceksiniz.

  • Butonlar ve yazılar ETAP tahtasına uygun olarak daha büyük görünecek.

Kaynak Kod: https://github.com/nuritiras/etap_tam_ekran

Neden Kiosk Modu?

Bu örnekle öğrencilerinize/izleyicilerinize şunu anlatabilirsiniz: "Arkadaşlar, Akıllı Tahta (ETAP) uygulamaları geliştirirken kullanıcı deneyimi masaüstünden farklıdır. Öğretmen tahtaya dokunduğunda butonları rahatça bulabilmeli ve yanlışlıkla uygulamayı kapatmamalıdır. Bu yüzden 'Full Screen' ve büyük butonlar kullanıyoruz."


Bu aşamayı da tamamladık. Şu an elinizde:

  1. Pardus üzerinde çalışan,

  2. Sistemden IP bilgisi çeken,

  3. Tam ekran (Kiosk) modunda çalışan,

  4. Görsel öğeler içeren bir uygulama var.

Yorumlar

Bu blogdaki popüler yayınlar

Pardus ETAP 23 İçin Flutter ile Dijital "Öğrenci Seçici" Uygulaması

Uygulama: Pardus Logosunu Göster

Pardus ETAP 23 İçin Flutter ile Sanal Laboratuvar