Skip to content

Commit 9e426a1

Browse files
authored
Merge pull request #6 from rujin2003/dev
feat: appbar support
2 parents b60a72c + b898b7b commit 9e426a1

File tree

6 files changed

+186
-2
lines changed

6 files changed

+186
-2
lines changed

lib/flutter_sdui.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export 'src/widgets/sdui_container.dart';
3838
export 'src/widgets/sdui_scaffold.dart';
3939
export 'src/widgets/sdui_spacer.dart';
4040
export 'src/widgets/sdui_icon.dart';
41+
export 'src/widgets/sdui_appbar.dart';
4142

4243
// Network communication
4344
export 'src/service/sdui_grpc_client.dart';

lib/src/generated/sdui.pbenum.dart

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/src/parser/flutter_to_sdui.dart

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:flutter_sdui/src/widgets/sdui_container.dart';
88
import 'package:flutter_sdui/src/widgets/sdui_scaffold.dart';
99
import 'package:flutter_sdui/src/widgets/sdui_spacer.dart';
1010
import 'package:flutter_sdui/src/widgets/sdui_icon.dart';
11+
import 'package:flutter_sdui/src/widgets/sdui_appbar.dart';
1112
import 'package:flutter_sdui/src/widgets/sdui_widget.dart';
1213

1314
SduiWidget flutterToSdui(Widget widget) {
@@ -135,7 +136,25 @@ SduiWidget flutterToSdui(Widget widget) {
135136
applyTextScaling: widget.applyTextScaling,
136137
shadows: widget.shadows,
137138
);
139+
} else if (widget is AppBar) {
140+
return SduiAppBar(
141+
title: widget.title is Text ? (widget.title as Text).data : null,
142+
backgroundColor: widget.backgroundColor,
143+
foregroundColor: widget.foregroundColor,
144+
elevation: widget.elevation,
145+
centerTitle: widget.centerTitle,
146+
actions: widget.actions,
147+
leading: widget.leading,
148+
bottom: widget.bottom,
149+
toolbarHeight: widget.toolbarHeight,
150+
leadingWidth: widget.leadingWidth,
151+
automaticallyImplyLeading: widget.automaticallyImplyLeading,
152+
flexibleSpace: widget.flexibleSpace,
153+
titleSpacing: widget.titleSpacing,
154+
toolbarOpacity: widget.toolbarOpacity,
155+
bottomOpacity: widget.bottomOpacity,
156+
);
138157
}
139158
throw UnimplementedError(
140-
'Conversion for [38;5;9m${widget.runtimeType}[0m is not implemented');
159+
'Conversion for ${widget.runtimeType} is not implemented');
141160
}

lib/src/parser/sdui_proto_parser.dart

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'dart:developer';
33

44
import 'package:flutter/material.dart';
55
import 'package:flutter_sdui/src/generated/sdui.pb.dart';
6+
import 'package:flutter_sdui/src/widgets/sdui_appbar.dart';
67
import 'package:flutter_sdui/src/widgets/sdui_column.dart';
78
import 'package:flutter_sdui/src/widgets/sdui_container.dart';
89
import 'package:flutter_sdui/src/widgets/sdui_icon.dart';
@@ -55,6 +56,8 @@ class SduiParser {
5556
return _parseJsonSpacer(data);
5657
case 'icon':
5758
return _parseJsonIcon(data);
59+
case 'appbar':
60+
return _parseJsonAppBar(data);
5861
default:
5962
return SduiContainer();
6063
}
@@ -91,6 +94,8 @@ class SduiParser {
9194
return _parseProtoSpacer(data);
9295
case WidgetType.ICON:
9396
return _parseProtoIcon(data);
97+
case WidgetType.APPBAR:
98+
return _parseProtoAppBar(data);
9499
default:
95100
log('Unsupported widget type: ${data.type}');
96101
return SduiContainer();
@@ -407,6 +412,33 @@ class SduiParser {
407412
);
408413
}
409414

415+
static SduiAppBar _parseProtoAppBar(SduiWidgetData data) {
416+
String? title = data.stringAttributes['title'];
417+
Color? backgroundColor = data.hasBackgroundColor()
418+
? _parseProtoColor(data.backgroundColor)
419+
: null;
420+
double? elevation = data.doubleAttributes['elevation'];
421+
bool? centerTitle = data.boolAttributes['centerTitle'];
422+
423+
return SduiAppBar(
424+
title: title,
425+
backgroundColor: backgroundColor,
426+
foregroundColor: null,
427+
elevation: elevation,
428+
centerTitle: centerTitle,
429+
actions: null,
430+
leading: null,
431+
bottom: null,
432+
toolbarHeight: null,
433+
leadingWidth: null,
434+
automaticallyImplyLeading: null,
435+
flexibleSpace: null,
436+
titleSpacing: null,
437+
toolbarOpacity: null,
438+
bottomOpacity: null,
439+
);
440+
}
441+
410442
/// Helper methods for parsing protobuf attribute types into Flutter types.
411443
412444
/// Parses a string value into a [BoxFit] enum.
@@ -1223,6 +1255,60 @@ class SduiParser {
12231255
);
12241256
}
12251257

1258+
static SduiAppBar _parseJsonAppBar(Map<String, dynamic> data) {
1259+
List<Widget>? actions;
1260+
if (data['actions'] is List) {
1261+
actions = (data['actions'] as List)
1262+
.map((a) => SduiParser.parseJSON(a as Map<String, dynamic>).toFlutterWidget())
1263+
.toList();
1264+
}
1265+
1266+
Widget? leading;
1267+
if (data['leading'] != null) {
1268+
leading = SduiParser.parseJSON(data['leading'] as Map<String, dynamic>)
1269+
.toFlutterWidget();
1270+
}
1271+
1272+
Widget? flexibleSpace;
1273+
if (data['flexibleSpace'] != null) {
1274+
flexibleSpace =
1275+
SduiParser.parseJSON(data['flexibleSpace'] as Map<String, dynamic>)
1276+
.toFlutterWidget();
1277+
}
1278+
1279+
return SduiAppBar(
1280+
title: data['title']?.toString(),
1281+
backgroundColor: _parseJsonColor(data['backgroundColor']),
1282+
foregroundColor: _parseJsonColor(data['foregroundColor']),
1283+
elevation: (data['elevation'] is num)
1284+
? (data['elevation'] as num).toDouble()
1285+
: null,
1286+
centerTitle: data['centerTitle'] is bool ? data['centerTitle'] : null,
1287+
actions: actions,
1288+
leading: leading,
1289+
bottom: null, // Complex widget, needs special handling
1290+
toolbarHeight: (data['toolbarHeight'] is num)
1291+
? (data['toolbarHeight'] as num).toDouble()
1292+
: null,
1293+
leadingWidth: (data['leadingWidth'] is num)
1294+
? (data['leadingWidth'] as num).toDouble()
1295+
: null,
1296+
automaticallyImplyLeading: data['automaticallyImplyLeading'] is bool
1297+
? data['automaticallyImplyLeading']
1298+
: null,
1299+
flexibleSpace: flexibleSpace,
1300+
titleSpacing: (data['titleSpacing'] is num)
1301+
? (data['titleSpacing'] as num).toDouble()
1302+
: null,
1303+
toolbarOpacity: (data['toolbarOpacity'] is num)
1304+
? (data['toolbarOpacity'] as num).toDouble()
1305+
: null,
1306+
bottomOpacity: (data['bottomOpacity'] is num)
1307+
? (data['bottomOpacity'] as num).toDouble()
1308+
: null,
1309+
);
1310+
}
1311+
12261312
// --- JSON attribute helpers (implement as needed, similar to proto helpers) ---
12271313
static TextStyle? _parseJsonTextStyle(dynamic value) {
12281314
if (value is! Map<String, dynamic>) return null;

lib/src/protos/sdui.proto

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ enum WidgetType {
1414
SCAFFOLD = 7;
1515
SPACER = 8;
1616
ICON = 9;
17+
APPBAR = 10;
1718
// Add other widget types here
1819
}
1920

@@ -101,6 +102,20 @@ message SduiWidgetData {
101102
double opacity = 62;
102103
bool apply_text_scaling = 63;
103104
repeated ShadowData shadows = 64;
105+
106+
// AppBar specific attributes
107+
SduiWidgetData title_widget = 65; // For custom title widget
108+
ColorData foreground_color = 66;
109+
repeated SduiWidgetData actions = 67;
110+
SduiWidgetData leading = 68;
111+
SduiWidgetData bottom = 69;
112+
double toolbar_height = 70;
113+
double leading_width = 71;
114+
bool automatically_imply_leading = 72;
115+
SduiWidgetData flexible_space = 73;
116+
double title_spacing = 74;
117+
double toolbar_opacity = 75;
118+
double bottom_opacity = 76;
104119
}
105120

106121
// Message for Color

lib/src/widgets/sdui_appbar.dart

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_sdui/src/widgets/sdui_widget.dart';
3+
4+
/// Represents an AppBar widget in SDUI.
5+
class SduiAppBar extends SduiWidget {
6+
final String? title;
7+
final Color? backgroundColor;
8+
final Color? foregroundColor;
9+
final double? elevation;
10+
final bool? centerTitle;
11+
final List<Widget>? actions;
12+
final Widget? leading;
13+
final PreferredSizeWidget? bottom;
14+
final double? toolbarHeight;
15+
final double? leadingWidth;
16+
final bool? automaticallyImplyLeading;
17+
final Widget? flexibleSpace;
18+
final double? titleSpacing;
19+
final double? toolbarOpacity;
20+
final double? bottomOpacity;
21+
22+
SduiAppBar({
23+
this.title,
24+
this.backgroundColor,
25+
this.foregroundColor,
26+
this.elevation,
27+
this.centerTitle,
28+
this.actions,
29+
this.leading,
30+
this.bottom,
31+
this.toolbarHeight,
32+
this.leadingWidth,
33+
this.automaticallyImplyLeading,
34+
this.flexibleSpace,
35+
this.titleSpacing,
36+
this.toolbarOpacity,
37+
this.bottomOpacity,
38+
});
39+
40+
@override
41+
Widget toFlutterWidget() {
42+
return AppBar(
43+
title: title != null ? Text(title!) : null,
44+
backgroundColor: backgroundColor,
45+
foregroundColor: foregroundColor,
46+
elevation: elevation,
47+
centerTitle: centerTitle,
48+
actions: actions,
49+
leading: leading,
50+
bottom: bottom,
51+
toolbarHeight: toolbarHeight,
52+
leadingWidth: leadingWidth,
53+
automaticallyImplyLeading: automaticallyImplyLeading ?? true,
54+
flexibleSpace: flexibleSpace,
55+
titleSpacing: titleSpacing,
56+
toolbarOpacity: toolbarOpacity ?? 1.0,
57+
bottomOpacity: bottomOpacity ?? 1.0,
58+
);
59+
}
60+
}

0 commit comments

Comments
 (0)