blossom_tabs 4.0.0 copy "blossom_tabs: ^4.0.0" to clipboard
blossom_tabs: ^4.0.0 copied to clipboard

Blossom Tab Manger Package for Flutter Blossom and related projects.

example/lib/main.dart

import 'dart:convert';
import 'dart:math';

import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:blossom_tabs/blossom_tabs.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
  doWhenWindowReady(() {
    const initialSize = Size(800, 450);
    appWindow.minSize = initialSize;
    appWindow.size = initialSize;
    appWindow.alignment = Alignment.center;
    appWindow.show();
  });
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

Widget buildTab(
  BuildContext context, {
  required bool isActive,
  bool useRow = true,
  Widget? icon,
  Widget? activeIcon,
  String? title,
  TextStyle? style,
  TextStyle? activeStyle,
}) {
  var children = [
    (isActive ? activeIcon ?? icon : icon) ??
        const SizedBox(
          width: 10,
        ),
    if (title != null)
      Flexible(
        child: Text(
          title,
          softWrap: false,
          overflow: TextOverflow.fade,
          style: isActive ? activeStyle ?? style : style,
        ),
      ),
  ];
  return Padding(
    padding: const EdgeInsets.symmetric(horizontal: 4.0),
    child: useRow
        ? Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Row(children: children),
            ],
          )
        : Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: children,
              ),
            ],
          ),
  );
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var _controller = BlossomTabController<int>(tabs: []);
  var _tabs = <BlossomTab<int>>[];

  BlossomTab<int> _getTab(String e) => BlossomTab<int>(
        id: e,
        data: int.parse(e.codeUnits.join()),
        title: e.toUpperCase(),
        isSticky: e == 'd',
      );

  @override
  void initState() {
    _tabs = ['a', 'b', 'c', 'd', 'e']
        .map(
          (e) => _getTab(e),
          //     BlossomTab.fromJson<int>(
          //   {
          //     "id": e,
          //     "data": {"value": int.parse(e.codeUnits.join())},
          //     "title": e.toUpperCase(),
          //     "isSticky": e == 'd' ? true : false,
          //     "maxWidth": 200.0,
          //     "stickyWidth": 50.0
          //   },
          //   (map) => map['value'],
          // ),
        )
        .toList();
    _controller = BlossomTabController<int>(currentTab: 'b', tabs: _tabs);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return BlossomTabControllerScope(
      controller: _controller,
      child: Scaffold(
        appBar: PreferredSize(
          preferredSize: const Size.fromHeight(85),
          child: Stack(
            children: [
              MoveWindow(
                child: BlossomTabBar<int>(
                  height: 85,
                  bottomBarHeight: 40,
                  selectedColor: Colors.blue,
                  dragColor: Colors.blue.withOpacity(0.6),
                  stickyColor: Colors.white,
                  backgroundColor: Colors.blue.withOpacity(0.3),
                  dividerColor: Colors.blue,
                  bottomColor: Colors.blue,
                  margin: const EdgeInsets.only(left: 4, top: 4, right: 140),
                  tabBarMargin: 4,
                  tabBuilder: (context, tab, isActive) => buildTab(
                    context,
                    isActive: isActive,
                    title: tab.id,
                    activeStyle:
                        tab.id == 'd' ? null : const TextStyle(color: Colors.white),
                    icon: tab.id == 'd'
                        ? null
                        : const Padding(
                            padding: EdgeInsets.all(4.0),
                            child: Icon(
                              Icons.ac_unit,
                              size: 14,
                              color: Colors.black26,
                            ),
                          ),
                    activeIcon: tab.id == 'd'
                        ? null
                        : const Padding(
                            padding: EdgeInsets.all(8.0),
                            child: Icon(
                              Icons.ac_unit,
                              size: 14,
                              color: Colors.white,
                            ),
                          ),
                  ),
                  tabActions: (context, tab) => [
                    if (tab.id != 'd')
                      Listener(
                        onPointerDown: (_) {
                          _controller.removeTabById(tab.id);
                        },
                        child: const Padding(
                          padding: EdgeInsets.all(4.0),
                          child: Icon(
                            Icons.close,
                            size: 14,
                            color: Colors.white,
                          ),
                        ),
                      ),
                  ],
                  bottomBar: BlossomTabControllerScopeDescendant<int>(
                      builder: (context, controller) {
                    // Future.delayed(Duration.zero)
                    //     .then((_) => print(jsonEncode(controller.toJson())));
                    return Container(
                      color: controller.currentTab == 'd' ? Colors.white : null,
                    );
                  }),
                  actions: [
                    Padding(
                      padding: const EdgeInsets.only(left: 6.0),
                      child: NewTabBtn(
                        onTap: () {
                          final z = _controller.tabs.map((e) => e.id).toList()..sort();
                          var c = z.isEmpty ? 'a' : z.last;
                          final lastCharacter =
                              String.fromCharCode(c.codeUnitAt(c.length - 1) + 1);
                          c = c.substring(0, c.length - 1) + lastCharacter;
                          _controller.addTab(_getTab(c));
                        },
                      ),
                    )
                  ],
                ),
              ),
              Positioned(
                right: 0,
                child: WindowButtons(),
              ),
            ],
          ),
        ),
        body: Row(
          children: [
            BlossomVerticalTabBar<int>(
              width: 240,
              sideBarWidth: 180,
              selectedColor: Colors.blue,
              dragColor: Colors.blue.withOpacity(0.6),
              stickyColor: Colors.white,
              backgroundColor: Colors.blue.withOpacity(0.3),
              dividerColor: Colors.blue,
              sideBarColor: Colors.blue,
              margin: const EdgeInsets.only(left: 0, top: 0, right: 0, bottom: 40),
              tabBarMargin: 0,
              showIndicator: true,
              indicatorColor: Colors.white,
              tabBuilder: (context, tab, isActive) => buildTab(
                context,
                isActive: isActive,
                useRow: false,
                title: tab.id,
                activeStyle: tab.id == 'd' ? null : const TextStyle(color: Colors.white),
                activeIcon: tab.id == 'd'
                    ? null
                    : const Padding(
                        padding: EdgeInsets.all(8.0),
                        child: Icon(
                          Icons.ac_unit,
                          size: 14,
                          color: Colors.white,
                        ),
                      ),
              ),
              sideBar: BlossomTabControllerScopeDescendant<int>(
                  builder: (context, controller) {
                // Future.delayed(Duration.zero)
                //     .then((_) => print(jsonEncode(controller.toJson())));
                return Container(
                  color: controller.currentTab == 'd' ? Colors.white : null,
                );
              }),
              actions: [
                Padding(
                  padding: const EdgeInsets.only(top: 6.0),
                  child: NewTabBtn(
                    onTap: () {
                      final z = _controller.tabs.map((e) => e.id).toList()..sort();
                      var c = z.isEmpty ? 'a' : z.last;
                      final lastCharacter =
                          String.fromCharCode(c.codeUnitAt(c.length - 1) + 1);
                      c = c.substring(0, c.length - 1) + lastCharacter;
                      _controller.addTab(_getTab(c));
                    },
                  ),
                )
              ],
            ),
            Expanded(
              child: BlossomTabView<int>(
                builder: (tab) => ColorBox(
                  child: Center(child: ColorBox(child: Center(child: Text(tab.id)))),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class NewTabBtn extends StatefulWidget {
  const NewTabBtn({
    Key? key,
    required this.onTap,
  }) : super(key: key);
  final void Function() onTap;

  @override
  State<NewTabBtn> createState() => _NewTabBtnState();
}

class _NewTabBtnState extends State<NewTabBtn> {
  var _opacity = 0.1;
  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: widget.onTap,
      onHover: (h) => setState(() => _opacity = h ? 0.3 : 0.1),
      child: Container(
        padding: const EdgeInsets.all(2.0),
        color: Colors.blue.withOpacity(_opacity),
        child: const Icon(
          Icons.add,
          size: 22,
          color: Colors.white,
        ),
      ),
    );
  }
}

class ColorBox extends StatefulWidget {
  const ColorBox({Key? key, this.child}) : super(key: key);

  final Widget? child;

  @override
  _ColorBoxState createState() => _ColorBoxState();
}

class _ColorBoxState extends State<ColorBox> {
  Color? _color;

  _randomColor() => Color(0xFF000000 + Random().nextInt(0x00FFFFFF));

  @override
  void initState() {
    _color = _randomColor();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _color = _randomColor();
        });
      },
      child: Container(width: 150, height: 150, color: _color, child: widget.child),
    );
  }
}

final buttonColors = WindowButtonColors(
  iconNormal: Colors.blue,
  mouseOver: Colors.blue.withOpacity(0.2),
  mouseDown: Colors.blue,
);

final closeButtonColors = WindowButtonColors(
  mouseOver: Colors.red.withOpacity(0.9),
  mouseDown: Colors.red,
  iconNormal: Colors.blue,
);

class WindowButtons extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        MinimizeWindowButton(colors: buttonColors),
        MaximizeWindowButton(colors: buttonColors),
        CloseWindowButton(colors: closeButtonColors),
      ],
    );
  }
}
8
likes
110
pub points
0%
popularity

Publisher

verified publisherflutterblossom.com

Blossom Tab Manger Package for Flutter Blossom and related projects.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (LICENSE)

Dependencies

flutter, json_annotation, scoped_model

More

Packages that depend on blossom_tabs