closed #111 - Make grid image picker for widget eyes and mouth
This commit is contained in:
@@ -15,7 +15,10 @@ struct CreateWidgetView: View {
|
||||
@StateObject private var customWidget: CustomWidgetModel
|
||||
|
||||
@State private var mouth: CustomWidgetMouthOptions = CustomWidgetMouthOptions.defaultOption
|
||||
|
||||
@State private var showRightEyeImagePicker: Bool = false
|
||||
@State private var showLeftEyeImagePicker: Bool = false
|
||||
@State private var showMuthImagePicker: Bool = false
|
||||
|
||||
var widgetView: CustomWidgetView
|
||||
|
||||
private var randomElements: [AnyView]
|
||||
@@ -41,7 +44,7 @@ struct CreateWidgetView: View {
|
||||
widgetView = CustomWidgetView(customWidgetModel: customWidget)
|
||||
}
|
||||
|
||||
func update(eye: CustomWidgetEyes, eyeOption: CustomWidgetEyeOptions) {
|
||||
func update(eye: CustomWidgetEyes, eyeOption: CustomWidgeImageOptions) {
|
||||
switch eye {
|
||||
case .left:
|
||||
customWidget.leftEye = eyeOption
|
||||
@@ -59,14 +62,14 @@ struct CreateWidgetView: View {
|
||||
customWidget.rightEyeColor = Color.random()
|
||||
customWidget.mouthColor = Color.random()
|
||||
|
||||
update(eye: .left, eyeOption: CustomWidgetEyeOptions.allCases.randomElement()!)
|
||||
update(eye: .right, eyeOption: CustomWidgetEyeOptions.allCases.randomElement()!)
|
||||
update(mouthOption: CustomWidgetMouthOptions.allCases.randomElement()!)
|
||||
update(eye: .left, eyeOption: CustomWidgeImageOptions.allCases.randomElement()!)
|
||||
update(eye: .right, eyeOption: CustomWidgeImageOptions.allCases.randomElement()!)
|
||||
update(mouthOption: CustomWidgeImageOptions.allCases.randomElement()!)
|
||||
|
||||
update(background: CustomWidgetBackGroundOptions.allCases.randomElement()!)
|
||||
}
|
||||
|
||||
func update(mouthOption: CustomWidgetMouthOptions) {
|
||||
func update(mouthOption: CustomWidgeImageOptions) {
|
||||
customWidget.mouth = mouthOption
|
||||
}
|
||||
|
||||
@@ -87,6 +90,195 @@ struct CreateWidgetView: View {
|
||||
}
|
||||
}
|
||||
|
||||
var bottomBarButtons: some View {
|
||||
Group {
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
Button(action: {
|
||||
createRandom()
|
||||
}, label: {
|
||||
Image(systemName: "shuffle")
|
||||
.font(.title)
|
||||
.foregroundColor(Color(UIColor.white))
|
||||
|
||||
})
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.frame(height: 40)
|
||||
.background(.blue)
|
||||
|
||||
Button(action: {
|
||||
UserDefaultsStore.saveCustomWidget(widgetModel: customWidget, inUse: false)
|
||||
let impactMed = UIImpactFeedbackGenerator(style: .heavy)
|
||||
impactMed.impactOccurred()
|
||||
dismiss()
|
||||
}, label: {
|
||||
Text(String(localized: "create_widget_save"))
|
||||
.font(.title)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(Color(UIColor.white))
|
||||
|
||||
})
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.frame(height: 40)
|
||||
.background(.green)
|
||||
|
||||
Button(action: {
|
||||
UserDefaultsStore.saveCustomWidget(widgetModel: customWidget, inUse: true)
|
||||
let impactMed = UIImpactFeedbackGenerator(style: .heavy)
|
||||
impactMed.impactOccurred()
|
||||
dismiss()
|
||||
}, label: {
|
||||
Text(String(localized: "create_widget_use"))
|
||||
.font(.title)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(Color(UIColor.white))
|
||||
|
||||
})
|
||||
.frame(height: 40)
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.background(.pink)
|
||||
|
||||
if customWidget.isSaved {
|
||||
Button(action: {
|
||||
UserDefaultsStore.deleteCustomWidget(withUUID: customWidget.uuid)
|
||||
let impactMed = UIImpactFeedbackGenerator(style: .heavy)
|
||||
impactMed.impactOccurred()
|
||||
dismiss()
|
||||
}, label: {
|
||||
Image(systemName: "trash")
|
||||
.font(.title)
|
||||
.foregroundColor(Color(UIColor.white))
|
||||
|
||||
})
|
||||
.frame(height: 40)
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.background(.orange)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var colorOptions: some View {
|
||||
Group {
|
||||
VStack {
|
||||
HStack(spacing: 0) {
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_background_color"))
|
||||
ColorPicker("", selection: $customWidget.bgColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_inner_color"))
|
||||
ColorPicker("", selection: $customWidget.innerColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_face_outline_color"))
|
||||
ColorPicker("", selection: $customWidget.circleStrokeColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
}
|
||||
|
||||
HStack(spacing: 0) {
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_left_eye_color"))
|
||||
ColorPicker("", selection: $customWidget.leftEyeColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_right_eye_color"))
|
||||
ColorPicker("", selection: $customWidget.rightEyeColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_mouth_color"))
|
||||
ColorPicker("", selection: $customWidget.mouthColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
theme.currentTheme.secondaryBGColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var bgImageOptions: some View {
|
||||
Group {
|
||||
HStack {
|
||||
ForEach(CustomWidgetBackGroundOptions.selectable, id: \.self) { bg in
|
||||
Image(bg.rawValue, bundle: .main)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(minWidth: 10, idealWidth: 40, maxWidth: 40,
|
||||
minHeight: 10, idealHeight: 40, maxHeight: 40,
|
||||
alignment: .center)
|
||||
.onTapGesture {
|
||||
update(background: bg)
|
||||
}
|
||||
}
|
||||
mixBG
|
||||
.onTapGesture {
|
||||
update(background: .random)
|
||||
}
|
||||
|
||||
ColorPicker("", selection: $customWidget.bgOverlayColor)
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
theme.currentTheme.secondaryBGColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var faceImageOptions: some View {
|
||||
Group {
|
||||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_left_eye"))
|
||||
.onTapGesture(perform: {
|
||||
showLeftEyeImagePicker.toggle()
|
||||
})
|
||||
.foregroundColor(textColor)
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
Spacer()
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_right_eye"))
|
||||
.onTapGesture(perform: {
|
||||
showRightEyeImagePicker.toggle()
|
||||
})
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
Spacer()
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_mouth"))
|
||||
.onTapGesture(perform: {
|
||||
showMuthImagePicker.toggle()
|
||||
})
|
||||
.foregroundColor(textColor)
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
theme.currentTheme.secondaryBGColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
widgetView
|
||||
@@ -97,206 +289,34 @@ struct CreateWidgetView: View {
|
||||
|
||||
Divider().background(Color(UIColor.tertiarySystemBackground))
|
||||
|
||||
Group {
|
||||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
VStack(alignment: .center) {
|
||||
Menu(String(localized: "create_widget_view_left_eye")) {
|
||||
ForEach(CustomWidgetEyeOptions.allCases, id: \.self) { option in
|
||||
Button(action: {
|
||||
update(eye: .left, eyeOption: option)
|
||||
}, label: {
|
||||
Label(option.rawValue, image: option.rawValue)
|
||||
})
|
||||
}
|
||||
}
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
Spacer()
|
||||
VStack(alignment: .center) {
|
||||
Menu(String(localized: "create_widget_view_right_eye")) {
|
||||
ForEach(CustomWidgetEyeOptions.allCases, id: \.self) { option in
|
||||
Button(action: {
|
||||
update(eye: .right, eyeOption: option)
|
||||
}, label: {
|
||||
Label(option.rawValue, image: option.rawValue)
|
||||
})
|
||||
}
|
||||
}
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
Spacer()
|
||||
VStack(alignment: .center) {
|
||||
Menu(String(localized: "create_widget_view_mouth")) {
|
||||
ForEach(CustomWidgetMouthOptions.allCases, id: \.self) { option in
|
||||
Button(action: {
|
||||
update(mouthOption: option)
|
||||
}, label: {
|
||||
Label(option.rawValue, image: option.rawValue)
|
||||
})
|
||||
}
|
||||
}
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
theme.currentTheme.secondaryBGColor
|
||||
)
|
||||
}
|
||||
faceImageOptions
|
||||
|
||||
Divider().background(Color(UIColor.tertiarySystemBackground))
|
||||
|
||||
Group {
|
||||
HStack {
|
||||
ForEach(CustomWidgetBackGroundOptions.selectable, id: \.self) { bg in
|
||||
Image(bg.rawValue, bundle: .main)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(minWidth: 10, idealWidth: 40, maxWidth: 40,
|
||||
minHeight: 10, idealHeight: 40, maxHeight: 40,
|
||||
alignment: .center)
|
||||
.onTapGesture {
|
||||
update(background: bg)
|
||||
}
|
||||
}
|
||||
mixBG
|
||||
.onTapGesture {
|
||||
update(background: .random)
|
||||
}
|
||||
|
||||
ColorPicker("", selection: $customWidget.bgOverlayColor)
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
theme.currentTheme.secondaryBGColor
|
||||
)
|
||||
}
|
||||
|
||||
bgImageOptions
|
||||
|
||||
Divider().background(Color(UIColor.tertiarySystemBackground))
|
||||
|
||||
Group {
|
||||
VStack {
|
||||
HStack(spacing: 0) {
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_background_color"))
|
||||
ColorPicker("", selection: $customWidget.bgColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_inner_color"))
|
||||
ColorPicker("", selection: $customWidget.innerColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_face_outline_color"))
|
||||
ColorPicker("", selection: $customWidget.circleStrokeColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
}
|
||||
|
||||
HStack(spacing: 0) {
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_left_eye_color"))
|
||||
ColorPicker("", selection: $customWidget.leftEyeColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_right_eye_color"))
|
||||
ColorPicker("", selection: $customWidget.rightEyeColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text(String(localized: "create_widget_view_mouth_color"))
|
||||
ColorPicker("", selection: $customWidget.mouthColor)
|
||||
.labelsHidden()
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
theme.currentTheme.secondaryBGColor
|
||||
)
|
||||
}
|
||||
colorOptions
|
||||
|
||||
Divider().background(Color(UIColor.tertiarySystemBackground))
|
||||
|
||||
Group {
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
Button(action: {
|
||||
createRandom()
|
||||
}, label: {
|
||||
Image(systemName: "shuffle")
|
||||
.font(.title)
|
||||
.foregroundColor(Color(UIColor.white))
|
||||
|
||||
})
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.frame(height: 40)
|
||||
.background(.blue)
|
||||
|
||||
Button(action: {
|
||||
UserDefaultsStore.saveCustomWidget(widgetModel: customWidget, inUse: false)
|
||||
let impactMed = UIImpactFeedbackGenerator(style: .heavy)
|
||||
impactMed.impactOccurred()
|
||||
dismiss()
|
||||
}, label: {
|
||||
Text(String(localized: "create_widget_save"))
|
||||
.font(.title)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(Color(UIColor.white))
|
||||
|
||||
})
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.frame(height: 40)
|
||||
.background(.green)
|
||||
|
||||
Button(action: {
|
||||
UserDefaultsStore.saveCustomWidget(widgetModel: customWidget, inUse: true)
|
||||
let impactMed = UIImpactFeedbackGenerator(style: .heavy)
|
||||
impactMed.impactOccurred()
|
||||
dismiss()
|
||||
}, label: {
|
||||
Text(String(localized: "create_widget_use"))
|
||||
.font(.title)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(Color(UIColor.white))
|
||||
|
||||
})
|
||||
.frame(height: 40)
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.background(.pink)
|
||||
|
||||
if customWidget.isSaved {
|
||||
Button(action: {
|
||||
UserDefaultsStore.deleteCustomWidget(withUUID: customWidget.uuid)
|
||||
let impactMed = UIImpactFeedbackGenerator(style: .heavy)
|
||||
impactMed.impactOccurred()
|
||||
dismiss()
|
||||
}, label: {
|
||||
Image(systemName: "trash")
|
||||
.font(.title)
|
||||
.foregroundColor(Color(UIColor.white))
|
||||
|
||||
})
|
||||
.frame(height: 40)
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.background(.orange)
|
||||
}
|
||||
}
|
||||
}
|
||||
bottomBarButtons
|
||||
}
|
||||
.sheet(isPresented: $showRightEyeImagePicker) {
|
||||
ImagePickerGridView(pickedImageClosure: { image in
|
||||
update(eye: .right, eyeOption: image)
|
||||
})
|
||||
}
|
||||
.sheet(isPresented: $showLeftEyeImagePicker) {
|
||||
ImagePickerGridView(pickedImageClosure: { image in
|
||||
update(eye: .left, eyeOption: image)
|
||||
})
|
||||
}
|
||||
.sheet(isPresented: $showMuthImagePicker) {
|
||||
ImagePickerGridView(pickedImageClosure: { image in
|
||||
update(mouthOption: image)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user