creek

The AI Image Editor of 2030

lib/ui/widgets/canvas/canvas_bottom_bar.dart (4371B)


  1import 'package:flutter/material.dart';
  2import 'package:flutter_svg/flutter_svg.dart';
  3import 'package:creekui/ui/styles/variables.dart';
  4
  5class CanvasBottomBar extends StatelessWidget {
  6  final String? activeItem;
  7  final VoidCallback onMagicDraw;
  8  final VoidCallback onMedia;
  9  final VoidCallback onStylesheet;
 10  final VoidCallback onTools;
 11  final VoidCallback onText;
 12  final VoidCallback onSelect;
 13  final VoidCallback onPlugins;
 14  const CanvasBottomBar({
 15    super.key,
 16    this.activeItem,
 17    required this.onMagicDraw,
 18    required this.onMedia,
 19    required this.onStylesheet,
 20    required this.onTools,
 21    required this.onText,
 22    required this.onSelect,
 23    required this.onPlugins,
 24  });
 25
 26  @override
 27  Widget build(BuildContext context) {
 28    return Container(
 29      decoration: BoxDecoration(
 30        color: Variables.background,
 31        border: Border(top: BorderSide(color: Variables.borderSubtle)),
 32        boxShadow: [
 33          BoxShadow(
 34            color: Colors.black.withOpacity(0.05),
 35            blurRadius: 10,
 36            offset: const Offset(0, -5),
 37          ),
 38        ],
 39      ),
 40      child: SafeArea(
 41        top: false,
 42        child: Container(
 43          padding: const EdgeInsets.symmetric(vertical: 10),
 44          child: SingleChildScrollView(
 45            scrollDirection: Axis.horizontal,
 46            padding: const EdgeInsets.symmetric(horizontal: 16),
 47            child: Row(
 48              children: [
 49                _BottomBarItem(
 50                  label: "Magic Draw",
 51                  iconPath: "assets/icons/magic_draw.svg",
 52                  onTap: onMagicDraw,
 53                  isActive: activeItem == "Magic Draw",
 54                ),
 55                const SizedBox(width: 24),
 56                _BottomBarItem(
 57                  label: "Media",
 58                  iconPath: "assets/icons/media.svg",
 59                  onTap: onMedia,
 60                ),
 61                const SizedBox(width: 24),
 62                _BottomBarItem(
 63                  label: "Stylesheet",
 64                  iconPath: "assets/icons/stylesheet.svg",
 65                  onTap: onStylesheet,
 66                ),
 67                const SizedBox(width: 24),
 68                _BottomBarItem(
 69                  label: "Tools",
 70                  iconPath: "assets/icons/tools.svg",
 71                  onTap: onTools,
 72                ),
 73                const SizedBox(width: 24),
 74                _BottomBarItem(
 75                  label: "Text",
 76                  iconPath: "assets/icons/text.svg",
 77                  onTap: onText,
 78                  isActive: activeItem == "Text",
 79                ),
 80                const SizedBox(width: 24),
 81                _BottomBarItem(
 82                  label: "Select",
 83                  iconPath: "assets/icons/select.svg",
 84                  onTap: onSelect,
 85                ),
 86                const SizedBox(width: 24),
 87                _BottomBarItem(
 88                  label: "Plugins",
 89                  iconPath: "assets/icons/plugins.svg",
 90                  onTap: onPlugins,
 91                ),
 92              ],
 93            ),
 94          ),
 95        ),
 96      ),
 97    );
 98  }
 99}
100
101class _BottomBarItem extends StatelessWidget {
102  final String label;
103  final String iconPath;
104  final VoidCallback onTap;
105  final bool isActive;
106  const _BottomBarItem({
107    required this.label,
108    required this.iconPath,
109    required this.onTap,
110    this.isActive = false,
111  });
112  @override
113  Widget build(BuildContext context) {
114    final color = isActive ? Variables.iconActive : Variables.iconInactive;
115
116    return InkWell(
117      onTap: onTap,
118      borderRadius: BorderRadius.circular(8),
119      child: Padding(
120        padding: const EdgeInsets.all(8.0),
121        child: Column(
122          mainAxisAlignment: MainAxisAlignment.center,
123          mainAxisSize: MainAxisSize.min,
124          children: [
125            SvgPicture.asset(
126              iconPath,
127              width: 24,
128              height: 24,
129              colorFilter: ColorFilter.mode(color, BlendMode.srcIn),
130            ),
131            const SizedBox(height: 6),
132            Text(
133              label,
134              style: Variables.captionStyle.copyWith(
135                color: color,
136                fontWeight: isActive ? FontWeight.w600 : FontWeight.w500,
137                fontSize: 10,
138              ),
139            ),
140          ],
141        ),
142      ),
143    );
144  }
145}