flutter_host_device 0.1.0 copy "flutter_host_device: ^0.1.0" to clipboard
flutter_host_device: ^0.1.0 copied to clipboard

A Flutter widget that renders host devices with ports, fully programmatic — no SVG assets required.

example/lib/main.dart

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_host_device/flutter_host_device.dart';

void main() => runApp(const ExampleApp());

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

  @override
  State<ExampleApp> createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
  ThemeMode _themeMode = ThemeMode.dark;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutter_host_device demo',
      themeMode: _themeMode,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blueGrey,
          brightness: Brightness.light,
        ),
        useMaterial3: true,
      ),
      darkTheme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blueGrey,
          brightness: Brightness.dark,
        ),
        useMaterial3: true,
      ),
      home: DemoPage(
        themeMode: _themeMode,
        onThemeModeChanged: (mode) => setState(() => _themeMode = mode),
      ),
    );
  }
}

class DemoPage extends StatefulWidget {
  const DemoPage({
    super.key,
    required this.themeMode,
    required this.onThemeModeChanged,
  });

  final ThemeMode themeMode;
  final ValueChanged<ThemeMode> onThemeModeChanged;

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  static const _portCounts = [1, 2, 3, 4, 5, 6];

  int _selectedPortCount = 5;
  Map<int, PortStatus> _portStatuses = {};
  bool _isConfig = false;
  bool _useCustomLabels = false;
  final List<String> _eventLog = [];

  static const _customLabels = {
    1: 'eth0',
    2: 'eth1',
    3: 'MGMT',
    4: 'HA',
    5: 'iLO',
    6: 'SAN',
  };

  void _randomizeStatuses() {
    final rng = Random();
    final statuses = <int, PortStatus>{};
    for (int i = 1; i <= _selectedPortCount; i++) {
      statuses[i] = PortStatus.values[rng.nextInt(PortStatus.values.length)];
    }
    setState(() => _portStatuses = statuses);
  }

  void _log(String event) {
    setState(() {
      _eventLog.insert(0, event);
      if (_eventLog.length > 20) _eventLog.removeLast();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('flutter_host_device demo')),
      body: Column(
        children: [
          // Controls
          Padding(
            padding: const EdgeInsets.all(12),
            child: Wrap(
              spacing: 12,
              runSpacing: 8,
              crossAxisAlignment: WrapCrossAlignment.center,
              children: [
                DropdownButton<int>(
                  value: _selectedPortCount,
                  items: _portCounts
                      .map((c) => DropdownMenuItem(
                            value: c,
                            child: Text('$c ports'),
                          ))
                      .toList(),
                  onChanged: (v) => setState(() {
                    _selectedPortCount = v!;
                    _portStatuses = {};
                  }),
                ),
                ElevatedButton(
                  onPressed: _randomizeStatuses,
                  child: const Text('Randomize statuses'),
                ),
                Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    const Text('Config'),
                    Switch(
                      value: _isConfig,
                      onChanged: (v) => setState(() => _isConfig = v),
                    ),
                  ],
                ),
                Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    const Text('Custom labels'),
                    Switch(
                      value: _useCustomLabels,
                      onChanged: (v) => setState(() => _useCustomLabels = v),
                    ),
                  ],
                ),
                SegmentedButton<ThemeMode>(
                  segments: const [
                    ButtonSegment(value: ThemeMode.dark, label: Text('Dark')),
                    ButtonSegment(value: ThemeMode.light, label: Text('Light')),
                    ButtonSegment(
                        value: ThemeMode.system, label: Text('Auto')),
                  ],
                  selected: {widget.themeMode},
                  onSelectionChanged: (s) =>
                      widget.onThemeModeChanged(s.first),
                ),
              ],
            ),
          ),

          // Host device view
          Expanded(
            child: Center(
              child: LayoutBuilder(
                builder: (context, constraints) {
                  final viewSize = Size(
                    constraints.maxWidth.clamp(400, 1200),
                    constraints.maxHeight.clamp(200, 800),
                  );
                  return HostDeviceView(
                    size: viewSize,
                    portCount: _selectedPortCount,
                    portStatuses: _portStatuses,
                    portLabels: _useCustomLabels ? _customLabels : const {},
                    isConfig: _isConfig,
                    centerLabel: 'Host-Server-01',
                    onPortHover: (port) => _log('Hover: port $port'),
                    onPortHoverExit: () {},
                    onPortTap: (port) => _log('Tap: port $port'),
                    onHostHover: () {},
                    onHostHoverExit: () {},
                  );
                },
              ),
            ),
          ),

          // Event log
          Container(
            height: 120,
            width: double.infinity,
            color: Theme.of(context).brightness == Brightness.dark
                ? Colors.grey.shade900
                : Colors.grey.shade100,
            padding: const EdgeInsets.all(8),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('Event Log',
                    style: TextStyle(fontWeight: FontWeight.bold)),
                Expanded(
                  child: ListView(
                    children: _eventLog
                        .map((e) => Text(e,
                            style: const TextStyle(
                                fontSize: 12, fontFamily: 'monospace')))
                        .toList(),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
1
likes
0
points
165
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter widget that renders host devices with ports, fully programmatic — no SVG assets required.

Repository (GitHub)
View/report issues

Topics

#widget #network #host #visualization

License

unknown (license)

Dependencies

flutter, topology_view_icons

More

Packages that depend on flutter_host_device