Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/flutter_sdui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export 'src/widgets/sdui_container.dart';
export 'src/widgets/sdui_scaffold.dart';
export 'src/widgets/sdui_spacer.dart';
export 'src/widgets/sdui_icon.dart';
export 'src/widgets/sdui_appbar.dart';

// Network communication
export 'src/service/sdui_grpc_client.dart';
Expand Down
5 changes: 4 additions & 1 deletion lib/src/generated/sdui.pbenum.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion lib/src/parser/flutter_to_sdui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:flutter_sdui/src/widgets/sdui_container.dart';
import 'package:flutter_sdui/src/widgets/sdui_scaffold.dart';
import 'package:flutter_sdui/src/widgets/sdui_spacer.dart';
import 'package:flutter_sdui/src/widgets/sdui_icon.dart';
import 'package:flutter_sdui/src/widgets/sdui_appbar.dart';
import 'package:flutter_sdui/src/widgets/sdui_widget.dart';

SduiWidget flutterToSdui(Widget widget) {
Expand Down Expand Up @@ -135,7 +136,25 @@ SduiWidget flutterToSdui(Widget widget) {
applyTextScaling: widget.applyTextScaling,
shadows: widget.shadows,
);
} else if (widget is AppBar) {
return SduiAppBar(
title: widget.title is Text ? (widget.title as Text).data : null,
backgroundColor: widget.backgroundColor,
foregroundColor: widget.foregroundColor,
elevation: widget.elevation,
centerTitle: widget.centerTitle,
actions: widget.actions,
leading: widget.leading,
bottom: widget.bottom,
toolbarHeight: widget.toolbarHeight,
leadingWidth: widget.leadingWidth,
automaticallyImplyLeading: widget.automaticallyImplyLeading,
flexibleSpace: widget.flexibleSpace,
titleSpacing: widget.titleSpacing,
toolbarOpacity: widget.toolbarOpacity,
bottomOpacity: widget.bottomOpacity,
);
}
throw UnimplementedError(
'Conversion for ${widget.runtimeType} is not implemented');
'Conversion for ${widget.runtimeType} is not implemented');
}
86 changes: 86 additions & 0 deletions lib/src/parser/sdui_proto_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_sdui/src/generated/sdui.pb.dart';
import 'package:flutter_sdui/src/widgets/sdui_appbar.dart';
import 'package:flutter_sdui/src/widgets/sdui_column.dart';
import 'package:flutter_sdui/src/widgets/sdui_container.dart';
import 'package:flutter_sdui/src/widgets/sdui_icon.dart';
Expand Down Expand Up @@ -55,6 +56,8 @@ class SduiParser {
return _parseJsonSpacer(data);
case 'icon':
return _parseJsonIcon(data);
case 'appbar':
return _parseJsonAppBar(data);
default:
return SduiContainer();
}
Expand Down Expand Up @@ -91,6 +94,8 @@ class SduiParser {
return _parseProtoSpacer(data);
case WidgetType.ICON:
return _parseProtoIcon(data);
case WidgetType.APPBAR:
return _parseProtoAppBar(data);
default:
log('Unsupported widget type: ${data.type}');
return SduiContainer();
Expand Down Expand Up @@ -407,6 +412,33 @@ class SduiParser {
);
}

static SduiAppBar _parseProtoAppBar(SduiWidgetData data) {
String? title = data.stringAttributes['title'];
Color? backgroundColor = data.hasBackgroundColor()
? _parseProtoColor(data.backgroundColor)
: null;
double? elevation = data.doubleAttributes['elevation'];
bool? centerTitle = data.boolAttributes['centerTitle'];

return SduiAppBar(
title: title,
backgroundColor: backgroundColor,
foregroundColor: null,
elevation: elevation,
centerTitle: centerTitle,
actions: null,
leading: null,
bottom: null,
toolbarHeight: null,
leadingWidth: null,
automaticallyImplyLeading: null,
flexibleSpace: null,
titleSpacing: null,
toolbarOpacity: null,
bottomOpacity: null,
);
}

/// Helper methods for parsing protobuf attribute types into Flutter types.

/// Parses a string value into a [BoxFit] enum.
Expand Down Expand Up @@ -1223,6 +1255,60 @@ class SduiParser {
);
}

static SduiAppBar _parseJsonAppBar(Map<String, dynamic> data) {
List<Widget>? actions;
if (data['actions'] is List) {
actions = (data['actions'] as List)
.map((a) => SduiParser.parseJSON(a as Map<String, dynamic>).toFlutterWidget())
.toList();
}

Widget? leading;
if (data['leading'] != null) {
leading = SduiParser.parseJSON(data['leading'] as Map<String, dynamic>)
.toFlutterWidget();
}

Widget? flexibleSpace;
if (data['flexibleSpace'] != null) {
flexibleSpace =
SduiParser.parseJSON(data['flexibleSpace'] as Map<String, dynamic>)
.toFlutterWidget();
}

return SduiAppBar(
title: data['title']?.toString(),
backgroundColor: _parseJsonColor(data['backgroundColor']),
foregroundColor: _parseJsonColor(data['foregroundColor']),
elevation: (data['elevation'] is num)
? (data['elevation'] as num).toDouble()
: null,
centerTitle: data['centerTitle'] is bool ? data['centerTitle'] : null,
actions: actions,
leading: leading,
bottom: null, // Complex widget, needs special handling
toolbarHeight: (data['toolbarHeight'] is num)
? (data['toolbarHeight'] as num).toDouble()
: null,
leadingWidth: (data['leadingWidth'] is num)
? (data['leadingWidth'] as num).toDouble()
: null,
automaticallyImplyLeading: data['automaticallyImplyLeading'] is bool
? data['automaticallyImplyLeading']
: null,
flexibleSpace: flexibleSpace,
titleSpacing: (data['titleSpacing'] is num)
? (data['titleSpacing'] as num).toDouble()
: null,
toolbarOpacity: (data['toolbarOpacity'] is num)
? (data['toolbarOpacity'] as num).toDouble()
: null,
bottomOpacity: (data['bottomOpacity'] is num)
? (data['bottomOpacity'] as num).toDouble()
: null,
);
}

// --- JSON attribute helpers (implement as needed, similar to proto helpers) ---
static TextStyle? _parseJsonTextStyle(dynamic value) {
if (value is! Map<String, dynamic>) return null;
Expand Down
15 changes: 15 additions & 0 deletions lib/src/protos/sdui.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum WidgetType {
SCAFFOLD = 7;
SPACER = 8;
ICON = 9;
APPBAR = 10;
// Add other widget types here
}

Expand Down Expand Up @@ -101,6 +102,20 @@ message SduiWidgetData {
double opacity = 62;
bool apply_text_scaling = 63;
repeated ShadowData shadows = 64;

// AppBar specific attributes
SduiWidgetData title_widget = 65; // For custom title widget
ColorData foreground_color = 66;
repeated SduiWidgetData actions = 67;
SduiWidgetData leading = 68;
SduiWidgetData bottom = 69;
double toolbar_height = 70;
double leading_width = 71;
bool automatically_imply_leading = 72;
SduiWidgetData flexible_space = 73;
double title_spacing = 74;
double toolbar_opacity = 75;
double bottom_opacity = 76;
}

// Message for Color
Expand Down
60 changes: 60 additions & 0 deletions lib/src/widgets/sdui_appbar.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:flutter_sdui/src/widgets/sdui_widget.dart';

/// Represents an AppBar widget in SDUI.
class SduiAppBar extends SduiWidget {
final String? title;
final Color? backgroundColor;
final Color? foregroundColor;
final double? elevation;
final bool? centerTitle;
final List<Widget>? actions;
final Widget? leading;
final PreferredSizeWidget? bottom;
final double? toolbarHeight;
final double? leadingWidth;
final bool? automaticallyImplyLeading;
final Widget? flexibleSpace;
final double? titleSpacing;
final double? toolbarOpacity;
final double? bottomOpacity;

SduiAppBar({
this.title,
this.backgroundColor,
this.foregroundColor,
this.elevation,
this.centerTitle,
this.actions,
this.leading,
this.bottom,
this.toolbarHeight,
this.leadingWidth,
this.automaticallyImplyLeading,
this.flexibleSpace,
this.titleSpacing,
this.toolbarOpacity,
this.bottomOpacity,
});

@override
Widget toFlutterWidget() {
return AppBar(
title: title != null ? Text(title!) : null,
backgroundColor: backgroundColor,
foregroundColor: foregroundColor,
elevation: elevation,
centerTitle: centerTitle,
actions: actions,
leading: leading,
bottom: bottom,
toolbarHeight: toolbarHeight,
leadingWidth: leadingWidth,
automaticallyImplyLeading: automaticallyImplyLeading ?? true,
flexibleSpace: flexibleSpace,
titleSpacing: titleSpacing,
toolbarOpacity: toolbarOpacity ?? 1.0,
bottomOpacity: bottomOpacity ?? 1.0,
);
}
}
Loading