This commit is contained in:
Trey t
2025-12-09 23:37:04 -06:00
parent 3a10b4b8d6
commit f2565678be
1587 changed files with 7747 additions and 647 deletions

View File

@@ -0,0 +1,374 @@
//
// CustomIcon.swift
// Feels (iOS)
//
// Created by Trey Tartt on 2/13/22.
//
import SwiftUI
class CustomWidgetModel: ObservableObject, Codable, NSCopying {
static let numberOfBGItems = 109
static var randomWidget: CustomWidgetModel {
return CustomWidgetModel(leftEye: CustomWidgeImageOptions.defaultOption,
rightEye: CustomWidgeImageOptions.defaultOption,
mouth: CustomWidgeImageOptions.defaultOption,
background: CustomWidgetBackGroundOptions.defaultOption,
bgColor: Color.random(),
innerColor: Color.random(),
bgOverlayColor: Color.random(),
rightEyeColor: Color.random(),
leftEyeColor: Color.random(),
mouthColor: Color.random(),
circleStrokeColor: Color.random(),
inUse: true,
uuid: UUID().uuidString,
isSaved: false,
createdDate: Date())
}
init(leftEye: CustomWidgeImageOptions,
rightEye: CustomWidgeImageOptions,
mouth: CustomWidgeImageOptions,
background: CustomWidgetBackGroundOptions,
bgColor: Color,
innerColor: Color,
bgOverlayColor: Color,
rightEyeColor: Color,
leftEyeColor: Color,
mouthColor: Color,
circleStrokeColor: Color,
inUse: Bool,
uuid: String,
isSaved: Bool,
createdDate: Date) {
self.leftEye = leftEye
self.rightEye = rightEye
self.mouth = mouth
self.background = background
self.bgColor = bgColor
self.innerColor = innerColor
self.bgOverlayColor = bgOverlayColor
self.rightEyeColor = rightEyeColor
self.leftEyeColor = leftEyeColor
self.mouthColor = mouthColor
self.circleStrokeColor = circleStrokeColor
self.inUse = inUse
self.uuid = uuid
self.isSaved = isSaved
self.createdDate = createdDate
}
@Published var leftEye: CustomWidgeImageOptions
@Published var rightEye: CustomWidgeImageOptions
@Published var mouth: CustomWidgeImageOptions
@Published var background: CustomWidgetBackGroundOptions
@Published var bgColor: Color
@Published var innerColor: Color
@Published var bgOverlayColor: Color
@Published var leftEyeColor: Color
@Published var rightEyeColor: Color
@Published var mouthColor: Color
@Published var circleStrokeColor: Color
@Published var inUse: Bool
@Published var uuid: String
@Published var isSaved: Bool
@Published var createdDate: Date
private var oldBackground: CustomWidgetBackGroundOptions?
private var oldBackgroundImages: [(Image, String)]?
public var backgroundImages : [(Image, String)] {
if let oldBackgroundImages = oldBackgroundImages,
oldBackground == background {
return oldBackgroundImages
}
oldBackground = background
if background == .random {
var blah = [(Image, String)]()
for _ in 0...CustomWidgetModel.numberOfBGItems {
let image = CustomWidgetBackGroundOptions.selectable.randomElement()?.image ?? CustomWidgetBackGroundOptions.defaultOption.image
blah.append((image, UUID().uuidString))
}
oldBackgroundImages = blah
} else {
var blah = [(Image, String)]()
for _ in 0...CustomWidgetModel.numberOfBGItems {
blah.append((background.image, UUID().uuidString))
}
oldBackgroundImages = blah
}
return oldBackgroundImages!
}
enum CodingKeys: CodingKey {
case leftEye, rightEye, mouth, background, bgColor, innerColor, bgOverlayColor, leftEyeColor, rightEyeColor, mouthColor, circleStrokeColor, inUse, uuid, isSaved, createdDate
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
leftEye = try container.decode(CustomWidgeImageOptions.self, forKey: .leftEye)
rightEye = try container.decode(CustomWidgeImageOptions.self, forKey: .rightEye)
mouth = try container.decode(CustomWidgeImageOptions.self, forKey: .mouth)
background = try container.decode(CustomWidgetBackGroundOptions.self, forKey: .background)
bgColor = try container.decode(Color.self, forKey: .bgColor)
innerColor = try container.decode(Color.self, forKey: .innerColor)
bgOverlayColor = try container.decode(Color.self, forKey: .bgOverlayColor)
leftEyeColor = try container.decode(Color.self, forKey: .leftEyeColor)
rightEyeColor = try container.decode(Color.self, forKey: .rightEyeColor)
mouthColor = try container.decode(Color.self, forKey: .mouthColor)
circleStrokeColor = try container.decode(Color.self, forKey: .circleStrokeColor)
inUse = try container.decode(Bool.self, forKey: .inUse)
uuid = try container.decode(String.self, forKey: .uuid)
isSaved = try container.decode(Bool.self, forKey: .isSaved)
createdDate = try container.decode(Date.self, forKey: .createdDate)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(leftEye, forKey: .leftEye)
try container.encode(rightEye, forKey: .rightEye)
try container.encode(mouth, forKey: .mouth)
try container.encode(background, forKey: .background)
try container.encode(bgColor, forKey: .bgColor)
try container.encode(innerColor, forKey: .innerColor)
try container.encode(bgOverlayColor, forKey: .bgOverlayColor)
try container.encode(leftEyeColor, forKey: .leftEyeColor)
try container.encode(rightEyeColor, forKey: .rightEyeColor)
try container.encode(mouthColor, forKey: .mouthColor)
try container.encode(circleStrokeColor, forKey: .circleStrokeColor)
try container.encode(inUse, forKey: .inUse)
try container.encode(uuid, forKey: .uuid)
try container.encode(isSaved, forKey: .isSaved)
try container.encode(createdDate, forKey: .createdDate)
}
func copy(with zone: NSZone? = nil) -> Any {
let copy = CustomWidgetModel(leftEye: self.leftEye,
rightEye: self.rightEye,
mouth: self.mouth,
background: self.background,
bgColor: self.bgColor,
innerColor: self.innerColor,
bgOverlayColor: self.bgOverlayColor,
rightEyeColor: self.rightEyeColor,
leftEyeColor: self.leftEyeColor,
mouthColor: self.mouthColor,
circleStrokeColor: self.circleStrokeColor,
inUse: self.inUse,
uuid: self.uuid,
isSaved: self.isSaved,
createdDate: self.createdDate)
return copy
}
}
enum CustomWidgetBackGroundOptions: String, CaseIterable, Codable {
case horrible
case bad
case average
case good
case great
case random
static var selectable: [CustomWidgetBackGroundOptions] {
return [.great, .good, .average, .bad, .horrible]
}
static public var defaultOption: CustomWidgetBackGroundOptions {
CustomWidgetBackGroundOptions.random
}
public var image: Image {
return Image(self.rawValue, bundle: .main)
}
}
enum CustomWidgetEyes: String, Codable {
case left
case right
}
enum CustomWidgeImageOptions: String, CaseIterable, Codable {
case star_solid = "custom_icon/star-solid"
case jet_fighter_solid = "custom_icon/jet-fighter-solid"
case circle_xmark_solid = "custom_icon/circle-xmark-solid"
case frown_regular = "custom_icon/frown-regular"
case virus_covid_solid = "custom_icon/virus-covid-solid"
case bullhorn_solid = "custom_icon/bullhorn-solid"
case caret_down_solid = "custom_icon/caret-down-solid"
case meteor_solid = "custom_icon/meteor-solid"
case eye_solid = "custom_icon/eye-solid"
case battery_half_solid = "custom_icon/battery-half-solid"
case heart_crack_solid = "custom_icon/heart-crack-solid"
case heart_solid = "custom_icon/heart-solid"
case divide_solid = "custom_icon/divide-solid"
case location_crosshairs_solid = "custom_icon/location-crosshairs-solid"
case bitcoin_brands = "custom_icon/bitcoin-brands"
case baby_solid = "custom_icon/baby-solid"
case grin_regular = "custom_icon/grin-regular"
case poo_storm_solid = "custom_icon/poo-storm-solid"
case btc_brands = "custom_icon/btc-brands"
case shuttle_space_solid = "custom_icon/shuttle-space-solid"
case chess_king_solid = "custom_icon/chess-king-solid"
case chess_queen_solid = "custom_icon/chess-queen-solid"
case lightbulb_solid = "custom_icon/lightbulb-solid"
case skull_solid = "custom_icon/skull-solid"
case dice_one_solid = "custom_icon/dice-one-solid"
case fan_solid = "custom_icon/fan-solid"
case bolt_solid = "custom_icon/bolt-solid"
case dharmachakra_solid = "custom_icon/dharmachakra-solid"
case ban_solid = "custom_icon/ban-solid"
case skull_crossbones_solid = "custom_icon/skull-crossbones-solid"
case sad_tear_regular = "custom_icon/sad-tear-regular"
case floppy_disk_solid = "custom_icon/floppy-disk-solid"
case crosshairs_solid = "custom_icon/crosshairs-solid"
case exclamation_solid = "custom_icon/exclamation-solid"
case lemon_solid = "custom_icon/lemon-solid"
case caret_right_solid = "custom_icon/caret-right-solid"
case poo_solid = "custom_icon/poo-solid"
case rainbow_solid = "custom_icon/rainbow-solid"
case apple_brands = "custom_icon/apple-brands"
case x_solid = "custom_icon/x-solid"
case pizza_slice_solid = "custom_icon/pizza-slice-solid"
case empire_brands = "custom_icon/empire-brands"
case caret_up_solid = "custom_icon/caret-up-solid"
case life_ring_solid = "custom_icon/life-ring-solid"
case dragon_solid = "custom_icon/dragon-solid"
case cannabis_solid = "custom_icon/cannabis-solid"
case bullseye_solid = "custom_icon/bullseye-solid"
case code_compare_solid = "custom_icon/code-compare-solid"
case battery_empty_solid = "custom_icon/battery-empty-solid"
case moon_solid = "custom_icon/moon-solid"
case android_brands = "custom_icon/android-brands"
case smile_beam_regular = "custom_icon/smile-beam-regular"
case futbol_solid = "custom_icon/futbol-solid"
case dollar_sign_solid = "custom_icon/dollar-sign-solid"
case cross_solid = "custom_icon/cross-solid"
case bomb_solid = "custom_icon/bomb-solid"
case battery_full_solid = "custom_icon/battery-full-solid"
case arrow_up_solid = "custom_icon/arrow-up-solid"
case gem_solid = "custom_icon/gem-solid"
case code_solid = "custom_icon/code-solid"
case bolt_lightning_solid = "custom_icon/bolt-lightning-solid"
case caret_left_solid = "custom_icon/caret-left-solid"
case fort_awesome_brands = "custom_icon/fort-awesome-brands"
case fire_solid = "custom_icon/fire-solid"
case hotjar_brands = "custom_icon/hotjar-brands"
case burger_solid = "custom_icon/burger-solid"
case egg_solid = "custom_icon/egg-solid"
case meh_regular = "custom_icon/meh-regular"
case battery_three_quarters_solid = "custom_icon/battery-three-quarters-solid"
case crown_solid = "custom_icon/crown-solid"
case clock_solid = "custom_icon/clock-solid"
case battery_quarter_solid = "custom_icon/battery-quarter-solid"
case fly_brands = "custom_icon/fly-brands"
case baseball_solid = "custom_icon/baseball-solid"
case dice_d20_solid = "custom_icon/dice-d20-solid"
case microphone_solid = "custom_icon/microphone-solid"
case peace_solid = "custom_icon/peace-solid"
static public var defaultOption: CustomWidgeImageOptions {
CustomWidgeImageOptions.bomb_solid
}
public var image: Image {
return Image(self.rawValue, bundle: .main)
}
}
enum CustomWidgetMouthOptions: String, CaseIterable, Codable {
case star_solid = "custom_icon/star-solid"
case jet_fighter_solid = "custom_icon/jet-fighter-solid"
case circle_xmark_solid = "custom_icon/circle-xmark-solid"
case frown_regular = "custom_icon/frown-regular"
case virus_covid_solid = "custom_icon/virus-covid-solid"
case bullhorn_solid = "custom_icon/bullhorn-solid"
case caret_down_solid = "custom_icon/caret-down-solid"
case meteor_solid = "custom_icon/meteor-solid"
case eye_solid = "custom_icon/eye-solid"
case battery_half_solid = "custom_icon/battery-half-solid"
case heart_crack_solid = "custom_icon/heart-crack-solid"
case heart_solid = "custom_icon/heart-solid"
case divide_solid = "custom_icon/divide-solid"
case location_crosshairs_solid = "custom_icon/location-crosshairs-solid"
case bitcoin_brands = "custom_icon/bitcoin-brands"
case baby_solid = "custom_icon/baby-solid"
case grin_regular = "custom_icon/grin-regular"
case poo_storm_solid = "custom_icon/poo-storm-solid"
case btc_brands = "custom_icon/btc-brands"
case shuttle_space_solid = "custom_icon/shuttle-space-solid"
case chess_king_solid = "custom_icon/chess-king-solid"
case chess_queen_solid = "custom_icon/chess-queen-solid"
case lightbulb_solid = "custom_icon/lightbulb-solid"
case skull_solid = "custom_icon/skull-solid"
case dice_one_solid = "custom_icon/dice-one-solid"
case fan_solid = "custom_icon/fan-solid"
case bolt_solid = "custom_icon/bolt-solid"
case dharmachakra_solid = "custom_icon/dharmachakra-solid"
case ban_solid = "custom_icon/ban-solid"
case skull_crossbones_solid = "custom_icon/skull-crossbones-solid"
case sad_tear_regular = "custom_icon/sad-tear-regular"
case floppy_disk_solid = "custom_icon/floppy-disk-solid"
case crosshairs_solid = "custom_icon/crosshairs-solid"
case exclamation_solid = "custom_icon/exclamation-solid"
case lemon_solid = "custom_icon/lemon-solid"
case caret_right_solid = "custom_icon/caret-right-solid"
case poo_solid = "custom_icon/poo-solid"
case rainbow_solid = "custom_icon/rainbow-solid"
case apple_brands = "custom_icon/apple-brands"
case x_solid = "custom_icon/x-solid"
case pizza_slice_solid = "custom_icon/pizza-slice-solid"
case empire_brands = "custom_icon/empire-brands"
case caret_up_solid = "custom_icon/caret-up-solid"
case life_ring_solid = "custom_icon/life-ring-solid"
case dragon_solid = "custom_icon/dragon-solid"
case cannabis_solid = "custom_icon/cannabis-solid"
case bullseye_solid = "custom_icon/bullseye-solid"
case code_compare_solid = "custom_icon/code-compare-solid"
case battery_empty_solid = "custom_icon/battery-empty-solid"
case moon_solid = "custom_icon/moon-solid"
case android_brands = "custom_icon/android-brands"
case smile_beam_regular = "custom_icon/smile-beam-regular"
case futbol_solid = "custom_icon/futbol-solid"
case dollar_sign_solid = "custom_icon/dollar-sign-solid"
case cross_solid = "custom_icon/cross-solid"
case bomb_solid = "custom_icon/bomb-solid"
case battery_full_solid = "custom_icon/battery-full-solid"
case arrow_up_solid = "custom_icon/arrow-up-solid"
case gem_solid = "custom_icon/gem-solid"
case code_solid = "custom_icon/code-solid"
case bolt_lightning_solid = "custom_icon/bolt-lightning-solid"
case caret_left_solid = "custom_icon/caret-left-solid"
case fort_awesome_brands = "custom_icon/fort-awesome-brands"
case fire_solid = "custom_icon/fire-solid"
case hotjar_brands = "custom_icon/hotjar-brands"
case burger_solid = "custom_icon/burger-solid"
case egg_solid = "custom_icon/egg-solid"
case meh_regular = "custom_icon/meh-regular"
case battery_three_quarters_solid = "custom_icon/battery-three-quarters-solid"
case crown_solid = "custom_icon/crown-solid"
case clock_solid = "custom_icon/clock-solid"
case battery_quarter_solid = "custom_icon/battery-quarter-solid"
case fly_brands = "custom_icon/fly-brands"
case baseball_solid = "custom_icon/baseball-solid"
case dice_d20_solid = "custom_icon/dice-d20-solid"
case microphone_solid = "custom_icon/microphone-solid"
case peace_solid = "custom_icon/peace-solid"
static public var defaultOption: CustomWidgetMouthOptions {
CustomWidgetMouthOptions.bomb_solid
}
public var image: Image {
return Image(self.rawValue, bundle: .main)
}
}

View File

@@ -0,0 +1,103 @@
//
// IconView.swift
// Feels (iOS)
//
// Created by Trey Tartt on 2/13/22.
//
import SwiftUI
struct CustomWidgetView: View {
@StateObject public var customWidgetModel: CustomWidgetModel
private let facePercSize = 0.6
let columns = [
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1),
GridItem(.flexible(minimum: 1, maximum: 100), spacing: 1)
]
var body: some View {
GeometryReader { geo in
ZStack {
Rectangle()
.fill(
customWidgetModel.bgColor
)
.frame(maxWidth: .infinity, maxHeight: .infinity)
LazyVGrid(columns: columns, alignment: .leading, spacing: 0) {
ForEach(customWidgetModel.backgroundImages, id: \.self.1) { (bgOption, uuid) in
bgOption
.resizable()
.aspectRatio(1, contentMode: .fill)
.foregroundColor(customWidgetModel.bgOverlayColor)
}
}
.scaleEffect(1.1)
.clipped()
.background(
.clear
)
Circle()
.strokeBorder(customWidgetModel.circleStrokeColor, lineWidth: geo.size.width * 0.045)
.background(Circle().fill(customWidgetModel.innerColor))
.frame(width: geo.size.width*facePercSize,
height: geo.size.height*facePercSize,
alignment: .center)
.alignmentGuide(.top, computeValue: { _ in
return geo.size.width/2
})
customWidgetModel.leftEye.image
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geo.size.width*0.12,
height: geo.size.height*0.12,
alignment: .center)
.position(x: geo.size.width*0.4,
y: geo.size.height*0.45)
.foregroundColor(customWidgetModel.leftEyeColor)
customWidgetModel.rightEye.image
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geo.size.width*0.12,
height: geo.size.height*0.12,
alignment: .center)
.position(x: geo.size.width*0.6,
y: geo.size.height*0.45)
.foregroundColor(customWidgetModel.rightEyeColor)
customWidgetModel.mouth.image
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geo.size.width*0.12,
height: geo.size.height*0.12,
alignment: .center)
.position(x: geo.size.width*0.5,
y: geo.size.height*0.65)
.foregroundColor(customWidgetModel.mouthColor)
}
.position(x: geo.size.width/2,
y: geo.size.height/2)
}
}
}
struct WidgetView_Previews: PreviewProvider {
static var previews: some View {
CustomWidgetView(customWidgetModel: CustomWidgetModel.randomWidget)
.frame(width: 256, height: 256, alignment: .center)
}
}