mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 14:25:02 +00:00
88 files reformatted — zero logic changes: - All views, components, and JS modules wrapped to 80-char margin - Long property bindings, ternaries, and strings broken at natural points - Theme.qml theme definitions expanded to multi-line - StyleVariables tokens wrapped - Section comment rulers trimmed to 80 chars Trade-off: LOC increases from line wrapping (compact single-line properties now span 2-3 lines). Content unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
212 lines
6.3 KiB
QML
212 lines
6.3 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
|
|
Button {
|
|
id: control
|
|
|
|
property string variant: "contained" // contained, outlined, text
|
|
// primary, secondary, error,
|
|
// warning, info, success
|
|
property string color: "primary"
|
|
property string size: "medium" // small, medium, large
|
|
property bool loading: false
|
|
// start, center, end
|
|
property string loadingPosition: "center"
|
|
property string startIcon: ""
|
|
property string endIcon: ""
|
|
property bool fullWidth: false
|
|
|
|
enabled: !loading
|
|
|
|
implicitHeight: {
|
|
switch(size) {
|
|
case "small": return 32
|
|
case "large": return 44
|
|
default: return 36
|
|
}
|
|
}
|
|
implicitWidth: fullWidth
|
|
? parent.width
|
|
: Math.max(
|
|
implicitHeight,
|
|
contentRow.implicitWidth
|
|
+ horizontalPadding * 2)
|
|
|
|
property int horizontalPadding: {
|
|
switch(size) {
|
|
case "small": return 12
|
|
case "large": return 20
|
|
default: return 16
|
|
}
|
|
}
|
|
|
|
font.pixelSize: size === "small"
|
|
? 12
|
|
: size === "large" ? 16 : 14
|
|
font.weight: Font.Medium
|
|
|
|
// Color palette
|
|
property color mainColor: {
|
|
switch(color) {
|
|
case "primary": return "#1976d2"
|
|
case "secondary": return "#9c27b0"
|
|
case "error": return "#d32f2f"
|
|
case "warning": return "#ed6c02"
|
|
case "info": return "#0288d1"
|
|
case "success": return "#2e7d32"
|
|
default: return "#1976d2"
|
|
}
|
|
}
|
|
|
|
property color darkColor: {
|
|
switch(color) {
|
|
case "primary": return "#1565c0"
|
|
case "secondary": return "#7b1fa2"
|
|
case "error": return "#c62828"
|
|
case "warning": return "#e65100"
|
|
case "info": return "#01579b"
|
|
case "success": return "#1b5e20"
|
|
default: return "#1565c0"
|
|
}
|
|
}
|
|
|
|
background: Rectangle {
|
|
radius: 4
|
|
color: {
|
|
if (!control.enabled && !control.loading)
|
|
return "#e0e0e0"
|
|
if (control.loading)
|
|
return Qt.lighter(control.mainColor, 1.2)
|
|
if (control.variant === "contained") {
|
|
return control.down
|
|
? control.darkColor
|
|
: control.hovered
|
|
? Qt.darker(
|
|
control.mainColor,
|
|
1.1)
|
|
: control.mainColor
|
|
}
|
|
if (control.variant === "outlined") {
|
|
return control.hovered
|
|
? Qt.rgba(
|
|
control.mainColor.r,
|
|
control.mainColor.g,
|
|
control.mainColor.b,
|
|
0.04)
|
|
: "transparent"
|
|
}
|
|
// text variant
|
|
return control.hovered
|
|
? Qt.rgba(
|
|
control.mainColor.r,
|
|
control.mainColor.g,
|
|
control.mainColor.b,
|
|
0.04)
|
|
: "transparent"
|
|
}
|
|
border.width: control.variant === "outlined" ? 1 : 0
|
|
border.color:
|
|
control.enabled || control.loading
|
|
? control.mainColor
|
|
: "#e0e0e0"
|
|
|
|
Behavior on color {
|
|
ColorAnimation { duration: 150 }
|
|
}
|
|
}
|
|
|
|
contentItem: RowLayout {
|
|
id: contentRow
|
|
spacing: 8
|
|
|
|
// Start loading indicator
|
|
BusyIndicator {
|
|
Layout.preferredWidth: 16
|
|
Layout.preferredHeight: 16
|
|
running: control.loading
|
|
&& control.loadingPosition === "start"
|
|
visible: control.loading
|
|
&& control.loadingPosition === "start"
|
|
palette.dark:
|
|
control.variant === "contained"
|
|
? "#ffffff"
|
|
: control.mainColor
|
|
}
|
|
|
|
// Start icon
|
|
Text {
|
|
visible: control.startIcon
|
|
&& !control.loading
|
|
text: control.startIcon
|
|
font.pixelSize: control.font.pixelSize
|
|
color:
|
|
control.variant === "contained"
|
|
? "#ffffff"
|
|
: control.mainColor
|
|
}
|
|
|
|
// Center loading indicator (replaces text)
|
|
BusyIndicator {
|
|
Layout.preferredWidth: 20
|
|
Layout.preferredHeight: 20
|
|
running: control.loading
|
|
&& control.loadingPosition === "center"
|
|
visible: control.loading
|
|
&& control.loadingPosition === "center"
|
|
palette.dark:
|
|
control.variant === "contained"
|
|
? "#ffffff"
|
|
: control.mainColor
|
|
}
|
|
|
|
// Button text
|
|
Text {
|
|
visible: !control.loading
|
|
|| control.loadingPosition !== "center"
|
|
text: control.text
|
|
font: control.font
|
|
color: {
|
|
if (!control.enabled
|
|
&& !control.loading)
|
|
return "#9e9e9e"
|
|
return control.variant === "contained"
|
|
? "#ffffff"
|
|
: control.mainColor
|
|
}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
|
|
// End icon
|
|
Text {
|
|
visible: control.endIcon
|
|
&& !control.loading
|
|
text: control.endIcon
|
|
font.pixelSize: control.font.pixelSize
|
|
color:
|
|
control.variant === "contained"
|
|
? "#ffffff"
|
|
: control.mainColor
|
|
}
|
|
|
|
// End loading indicator
|
|
BusyIndicator {
|
|
Layout.preferredWidth: 16
|
|
Layout.preferredHeight: 16
|
|
running: control.loading
|
|
&& control.loadingPosition === "end"
|
|
visible: control.loading
|
|
&& control.loadingPosition === "end"
|
|
palette.dark:
|
|
control.variant === "contained"
|
|
? "#ffffff"
|
|
: control.mainColor
|
|
}
|
|
}
|
|
|
|
Behavior on opacity {
|
|
NumberAnimation { duration: 150 }
|
|
}
|
|
}
|