├── .gitignore ├── README.md ├── electronics-layout └── arduino-wiring.fzz ├── images ├── .DS_Store ├── matrix-layout.jpg └── wiring-layout.png ├── word-clock ├── ClockElement.cpp ├── ClockElement.h └── word-clock.ino └── word_clock ├── .flutter-plugins-dependencies ├── .gitignore ├── .metadata ├── README.md ├── android ├── app │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── wordclock │ │ │ └── MainActivity.java │ │ └── res │ │ ├── drawable │ │ └── launch_background.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── launcher_icon.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── launcher_icon.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── launcher_icon.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── launcher_icon.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── launcher_icon.png │ │ └── values │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── clock_element_indices.txt ├── clock_text.txt ├── icon.png ├── logo.png ├── logo.svg └── word-clock.png ├── ios ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ ├── Flutter.podspec │ ├── Release.xcconfig │ └── flutter_export_environment.sh ├── Podfile ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── main.m ├── lib ├── clocks │ ├── clock_rest_commands.dart │ └── word_clock │ │ └── word_clock_rest_commands.dart ├── dialogs │ ├── clock_configuration_dialog.dart │ └── color_picker_dialog.dart ├── main.dart ├── model │ └── clock.dart ├── screens │ ├── configuration_screen.dart │ ├── home_screen.dart │ ├── main_screen.dart │ ├── select_clock.dart │ └── splash_screen.dart ├── util │ └── device_scanner.dart └── widgets │ ├── clock_list │ ├── clock_list.dart │ └── clock_list_item.dart │ ├── clocks │ └── word_clock │ │ ├── clock_element.dart │ │ └── word_clock.dart │ └── configuration_item.dart ├── pubspec.yaml └── test └── widget_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ArduinoWordClock 2 | A code repository for an arduino word clock 3 | 4 | This project was inspired by the QlockTwo word clock, which is uses the same basic code logic. 5 | Currently, the only language that is supported with this repository is German. 6 | This is due to the layout of the LED matrix and the hardcoded position of the LEDs in the code. 7 | 8 | However, this code can be used a basis of any word clock with an 11 x 11 LED matrix. 9 | 10 | The main file for this clock is the .ino file, which is the main file that runs on the Arduino. 11 | The other files, define a class that represent a word on the clock. 12 | These words include the words for the hours and minutes. 13 | The other words such as "vor" and "nach" are hard coded. 14 | 15 | ## Part List 16 | This project uses a few different components in order to show the time in the LED matrix. 17 | The following list is the part list required to recreate this word clock: 18 | - 121 LEDs. The LEDs that should be used are LED strips. Each strip contains 11 LEDs. Since there are 11 rows, 121 LEDs are required 19 | - DS1307 RTC. The RTC is used to control the LEDs and show the words on the clock 20 | - DS18B20 Temperature Sensor. The sensor is used to display the temperature of the room that the clock is in 21 | - GL5528 Photoresistor. The photoresistor is used to set the brightness of the LEDs depending on how bright it is in the room 22 | - 1 x 10k Ohm Resistor 23 | - 1 x 4.7k Ohm Resistor 24 | - Arduino UNO or any other microcontroller with an ATMega328P chip 25 | - HM-10 Bluetooth 4.0 Chip, available from DSD Tech on amazon.de 26 | 27 | ## LED Matrix Layout 28 | The LED matrix that is used in this project is an 11 x 11 matrix. 29 | The LEDs are set up as follows: 30 | 11 LED strips. Each strip is one row for the matrix. 31 | Each LED strip contains 11 LEDs, thus the LED matrix is an 11 x 11. 32 | 33 | The main entry point for the data and the power must be at the bottom left of the LED matrix. The data and power then travel from left to right, until reaching the last LED on the first strip. The next row is connected to the end of the first rows power, ground, and data pin, meaning that the second rows flow is from right to left. This continues all the way to the top where the last LED is at the top right of the LED matrix. 34 | 35 | The layout looks like follows: 36 |
37 |
38 | 39 | 40 | ## Setting Up the Wiring 41 | 42 | 43 | The above image shows the way to set up the wiring for the electronic components of this clock. The DS1307 is connected to the Arduinos SDA and SCL pins, while also being powered through the 5v and ground pin on the Arduino. The LEDs are controlled using the Arduinos pin 5 and also connect to the 5v and ground pins. 44 | 45 | ## ClockElement class 46 | The ClockElement class describes a numerical word on the clock. It contains the definition for the range of LEDs that need to be lit up to display the full word, the element type, either HOUR or MINUTE, and the numerical values that it represents it. The class is very minimal and covers the necessary words to describe the time. 47 | 48 | ## How do I Get This Code Up and Running on My Own Word Clock? 49 | After setting up the electronics for your word clock, as described above, all you have to do is clone this repository and open it in the Arduino IDE. Choose the board that you are using through the tools menu and select the correct USB port. After doing this, you can upload the code, like uploading every other code, by simply pressing the upload button. 50 | 51 | ## Required Additional Libraries 52 | This code uses a few etxernal libraries that made interfacing with the hardware easier. The following libraries need to be downloaded and placed into the Arduino IDEs library folder: 53 | - https://github.com/PaulStoffregen/Time 54 | - https://www.arduinolibraries.info/libraries/vector 55 | - https://www.arduinolibraries.info/libraries/ds1307-rtc 56 | - https://www.arduinolibraries.info/libraries/dallas-temperature 57 | - https://www.arduinolibraries.info/libraries/one-wire 58 | -------------------------------------------------------------------------------- /electronics-layout/arduino-wiring.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/electronics-layout/arduino-wiring.fzz -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/images/.DS_Store -------------------------------------------------------------------------------- /images/matrix-layout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/images/matrix-layout.jpg -------------------------------------------------------------------------------- /images/wiring-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/images/wiring-layout.png -------------------------------------------------------------------------------- /word-clock/ClockElement.cpp: -------------------------------------------------------------------------------- 1 | #include "ClockElement.h" 2 | #include "arduino.h" 3 | 4 | ClockElement::ClockElement(){ } 5 | 6 | ClockElement::ClockElement(int numericValueAM, int numericValuePM, int from, int to, CLOCK_ELEMENT_TYPE type){ 7 | _numericValueAM = numericValueAM; 8 | _numericValuePM = numericValuePM; 9 | _from = from; 10 | _to = to; 11 | _type = type; 12 | } 13 | 14 | int ClockElement::GetRangeFrom(){ 15 | return _from; 16 | } 17 | 18 | int ClockElement::GetRangeTo(){ 19 | return _to; 20 | } 21 | 22 | int ClockElement::GetNumericValueAM() { 23 | return _numericValueAM; 24 | } 25 | 26 | int ClockElement::GetNumericValuePM() { 27 | return _numericValuePM; 28 | } 29 | 30 | int ClockElement::GetNumericValuesArrayLength() { 31 | return _to - _from; 32 | } 33 | 34 | CLOCK_ELEMENT_TYPE ClockElement::GetClockElementType(){ 35 | return this->_type; 36 | } 37 | -------------------------------------------------------------------------------- /word-clock/ClockElement.h: -------------------------------------------------------------------------------- 1 | enum CLOCK_ELEMENT_TYPE{ 2 | HOUR, 3 | MINUTE, 4 | WORD 5 | }; 6 | 7 | class ClockElement { 8 | public: 9 | ClockElement(); 10 | ClockElement(int numericValueAM, int numericValuePM, int from, int rangeTo, CLOCK_ELEMENT_TYPE type); 11 | int GetRangeFrom(); 12 | int GetRangeTo(); 13 | int GetNumericValueAM(); 14 | int GetNumericValuePM(); 15 | CLOCK_ELEMENT_TYPE GetClockElementType(); 16 | int GetNumericValuesArrayLength(); 17 | 18 | private: 19 | CLOCK_ELEMENT_TYPE _type; 20 | int _numericValueAM; 21 | int _numericValuePM; 22 | int _from; 23 | int _to; 24 | int _range; 25 | }; 26 | -------------------------------------------------------------------------------- /word-clock/word-clock.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "ClockElement.h" 10 | 11 | //#define FASTLED_ESP8266_RAW_PIN_ORDER 12 | #define NUM_LEDS 125 13 | #define HEART_LEDS 10 14 | #define NUM_CLOCK_ELEMENTS 19 15 | 16 | #define DATA_PIN 5 17 | #define pResistor A5 18 | #define ONE_WIRE_BUS 7 19 | 20 | aREST rest = aREST(); 21 | CRGB leds[NUM_LEDS]; 22 | 23 | IPAddress ip(192, 168, 2, 177); 24 | 25 | /**************************************************** 26 | *****************CONFIGURE WIFI HERE***************** 27 | *****************************************************/ 28 | char ssid[32] = "Seip"; 29 | char pass[32] = "connect.me"; 30 | 31 | IPAddress gateway(192, 168, 2, 1); 32 | IPAddress subnet(255, 255, 255, 0); 33 | 34 | long utcOffsetInSeconds = 7200; 35 | boolean isConnectedToWifi = false; 36 | 37 | WiFiUDP ntpUDP; 38 | WiFiClient client; 39 | WiFiServer server(80); 40 | NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds); 41 | 42 | ClockElement timeClockElements[NUM_CLOCK_ELEMENTS]; 43 | 44 | // Eins, Zwei, Drei, Vier, Fünf, Sechs, Sieben, Acht, Neun, Zehn, Elf, Zwölf, Null, Fünf, Zehn, Viertel, Zwanzig, Halb 45 | int timeClockElementRangeFrom[NUM_CLOCK_ELEMENTS] = { 44, 51, 40, 33, 55, 22, 26, 18, 3, 0, 58, 13, -1, 117, 106, 92, 99, 62 }; 46 | int timeClockElementRangeTo[NUM_CLOCK_ELEMENTS] = { 48, 55, 44, 37, 59, 27, 32, 22, 7, 4, 61, 18, -1, 121, 110, 99, 106, 66 }; 47 | int heartLEDs[HEART_LEDS] = {38, 48, 62, 69, 83, 71, 81, 73, 58, 50 }; 48 | 49 | struct CURRENT_TIME { 50 | int hours; 51 | int minutes; 52 | 53 | CURRENT_TIME(int h, int m) { 54 | hours = h; 55 | minutes = m; 56 | } 57 | }; 58 | 59 | 60 | bool createdClockElements = false; 61 | void createClockElements() 62 | { 63 | createdClockElements = true; 64 | int clockElementIndex = 0; 65 | for (int i = 1; i <= 12; i++) 66 | { 67 | int numericValueAM = i; 68 | int numericValuePM = i + 12; 69 | 70 | if (i + 12 == 24) 71 | { 72 | numericValuePM = 0; 73 | } 74 | 75 | timeClockElements[clockElementIndex] = ClockElement(numericValueAM, numericValuePM, timeClockElementRangeFrom[i - 1], timeClockElementRangeTo[i - 1], HOUR); 76 | clockElementIndex++; 77 | } 78 | 79 | //Create the ClockElements for the minutes 80 | int minuteDistance = 60; 81 | int rangeIndex = 12; 82 | for (int i = 0; i <= 30; i += 5) 83 | { 84 | int numericValueAM = i; 85 | int numericValuePM = i + minuteDistance; 86 | 87 | if (i == 30) { 88 | rangeIndex--; 89 | } 90 | 91 | timeClockElements[clockElementIndex] = ClockElement(numericValueAM, numericValuePM, timeClockElementRangeFrom[rangeIndex], timeClockElementRangeTo[rangeIndex], MINUTE); 92 | 93 | rangeIndex++; 94 | minuteDistance -= 10; 95 | clockElementIndex++; 96 | } 97 | } 98 | 99 | 100 | void setup() 101 | { 102 | Serial.begin(9600); 103 | 104 | // Function to be exposed 105 | rest.function("clockcolor", setPixelColor); 106 | rest.function("clockconfiguration", configureClock); 107 | 108 | rest.function("wordclockfreya", showFreya); 109 | rest.function("setDST", setDST); 110 | 111 | //Opposite of beginAP is WiFi.begin 112 | WiFi.config(ip, gateway, subnet); 113 | WiFi.begin(ssid, pass); 114 | while ( WiFi.status() != WL_CONNECTED ) { 115 | delay ( 500 ); 116 | Serial.print ( "." ); 117 | } 118 | 119 | 120 | Serial.println(WiFi.localIP()); 121 | 122 | server.begin(); 123 | // you're connected now, so print out the status: 124 | createClockElements(); 125 | FastLED.addLeds(leds, NUM_LEDS); 126 | 127 | timeClient.begin(); 128 | } 129 | 130 | char color[3] = {255, 255, 255}; 131 | 132 | bool showUhrWord = true; 133 | void loop() 134 | { 135 | 136 | String clientRequest = ""; 137 | 138 | client = server.available(); // listen for incoming clients 139 | 140 | while (client.connected()) { 141 | rest.handle(client); 142 | handleClockFunctions(); 143 | } 144 | 145 | handleClockFunctions(); 146 | delay(100); 147 | } 148 | 149 | int setDST(String dst) { 150 | utcOffsetInSeconds = dst.toInt(); 151 | return 1; 152 | } 153 | 154 | int configureClock(String configuration) { 155 | Serial.println("Configuring clock with following parameters:"); 156 | String wifiSSID = ""; 157 | String wifiPassword = ""; 158 | String clockRoomName = ""; 159 | 160 | int beginningIndex = 0; 161 | int configIndex = 0; 162 | String wifiConfiguration[3]; 163 | while (configuration.indexOf(",", beginningIndex) != -1) { 164 | int index = configuration.indexOf(",", beginningIndex); 165 | wifiConfiguration[configIndex] = configuration.substring(beginningIndex, index); 166 | beginningIndex = index + 1; 167 | configIndex++; 168 | } 169 | 170 | wifiConfiguration[configIndex] = configuration.substring(beginningIndex, configuration.length()); 171 | 172 | for (int i = 0; i < 3; i++) { 173 | String wifiConfig = wifiConfiguration[i]; 174 | String configKeyValue[2]; 175 | configKeyValue[0] = wifiConfig.substring(0, wifiConfig.indexOf("=", 0)); 176 | configKeyValue[1] = wifiConfig.substring(configKeyValue[0].length() + 1, wifiConfig.length()); 177 | 178 | Serial.print(configKeyValue[0] + ": "); 179 | Serial.println(configKeyValue[1]); 180 | 181 | if (i == 0) { 182 | Serial.println(configKeyValue[0]); 183 | configKeyValue[0].toCharArray(ssid, configKeyValue[0].length() + 1); 184 | Serial.println(ssid); 185 | } else if (configKeyValue[0].equals("password")) { 186 | configKeyValue[1].toCharArray(pass, configKeyValue[1].length() + 1); 187 | } 188 | } 189 | 190 | return 1; 191 | } 192 | 193 | void handleClockFunctions() { 194 | 195 | CURRENT_TIME currentTime = getTimeFromNTPServer(); 196 | 197 | resetAllLEDs(); 198 | showBasicClockElements(); 199 | showMinuteLEDs(currentTime.minutes, currentTime.hours, showUhrWord); 200 | showHourLEDs(currentTime.hours); 201 | 202 | if (showUhrWord) 203 | { 204 | //Light up the LEDs for the word "UHR" 205 | leds[8] = CRGB(color[1], color[0], color[2]); 206 | leds[9] = CRGB(color[1], color[0], color[2]); 207 | leds[10] = CRGB(color[1], color[0], color[2]); 208 | } 209 | 210 | FastLED.show(); 211 | } 212 | 213 | CURRENT_TIME getTimeFromNTPServer() { 214 | timeClient.update(); 215 | delay(1000); 216 | return CURRENT_TIME(timeClient.getHours(), timeClient.getMinutes()); 217 | } 218 | 219 | int showFreya(String command) { 220 | showWordFreya(); 221 | } 222 | 223 | //http://192.168.4.1/rgb?param=1,2,3 224 | int setPixelColor(String rgb) { 225 | int beginningIndex = 0; 226 | int colorIndex = 0; 227 | while (rgb.indexOf(",", beginningIndex) != -1) { 228 | int index = rgb.indexOf(",", beginningIndex); 229 | Serial.println(rgb.substring(beginningIndex, index)); 230 | color[colorIndex] = rgb.substring(beginningIndex, index).toInt(); 231 | beginningIndex = index + 1; 232 | colorIndex++; 233 | } 234 | color[colorIndex] = rgb.substring(beginningIndex, rgb.length()).toInt(); 235 | 236 | FastLED.show(); 237 | // set single pixel color 238 | return 1; 239 | } 240 | 241 | void showHourLEDs(int &hours) { 242 | Serial.print("Hour to show: "); 243 | Serial.println(hours); 244 | 245 | ClockElement clockElement = findClockElementByNumericValueAndType(hours, HOUR); 246 | 247 | Serial.print("Hour that will be shown: "); 248 | Serial.println(clockElement.GetNumericValuePM()); 249 | Serial.println(""); 250 | 251 | setColorForClockElement(clockElement, color[1], color[0], color[2]); 252 | } 253 | 254 | void showMinuteLEDs(int minutes, int &hours, bool &showUhrWord) { 255 | if (minutes >= 0 && minutes < 5) { 256 | showUhrWord = true; 257 | } 258 | else { 259 | showUhrWord = false; 260 | } 261 | 262 | if (minutes != 0) { 263 | if ((minutes >= 25 && minutes < 30) || (minutes >= 35 && minutes < 40)) 264 | { 265 | ClockElement element = findClockElementByNumericValueAndType(5, MINUTE); 266 | setColorForClockElement(element, color[0], color[1], color[2]); 267 | 268 | if (minutes >= 25 && minutes < 30) 269 | { 270 | showWordVor(); 271 | } 272 | else if (minutes >= 35 && minutes < 40) 273 | { 274 | showWordNach(); 275 | } 276 | } 277 | 278 | if (60 - minutes > 35 && !(minutes >= 0 && minutes < 5)) 279 | { 280 | showWordNach(); 281 | } 282 | else if (60 - minutes < 25 && !(minutes >= 0 && minutes < 5)) 283 | { 284 | showWordVor(); 285 | } 286 | 287 | if (60 - minutes < 25 || (minutes >= 25 && minutes < 30) || 288 | (minutes >= 35 && minutes < 40) || (minutes >= 30 && minutes < 35)) { 289 | hours = hours + 1; 290 | } 291 | showLeftOverMinuteLEDs(minutes % 5); 292 | } 293 | 294 | ClockElement clockElement = findClockElementByNumericValueAndType(minutes - (minutes % 5), MINUTE); 295 | setColorForClockElement(clockElement, color[1], color[0], color[2]); 296 | } 297 | 298 | void showLeftOverMinuteLEDs(int leftOverMinutes) { 299 | for (int i = 124; i > 124 - leftOverMinutes; i--) { 300 | leds[i] = CRGB(color[1], color[0], color[2]); 301 | } 302 | } 303 | 304 | void resetAllLEDs() { 305 | //Reset time words 306 | for (int i = 0; i < NUM_LEDS; i++) { 307 | leds[i] = CRGB(0, 0, 0); 308 | } 309 | } 310 | 311 | void showBasicClockElements() { 312 | //Light up the LEDs for the word "ES" 313 | leds[110] = CRGB(color[1], color[0], color[2]); 314 | leds[111] = CRGB(color[1], color[0], color[2]); 315 | 316 | //Light up the LEDs for the word "IST" 317 | leds[113] = CRGB(color[1], color[0], color[2]); 318 | leds[114] = CRGB(color[1], color[0], color[2]); 319 | leds[115] = CRGB(color[1], color[0], color[2]); 320 | } 321 | 322 | void showWordVor() { 323 | //Light up the LEDs for the word "VOR" 324 | leds[85] = CRGB(color[1], color[0], color[2]); 325 | leds[86] = CRGB(color[1], color[0], color[2]); 326 | leds[87] = CRGB(color[1], color[0], color[2]); 327 | } 328 | 329 | void showWordNach() { 330 | //Light up the LEDs for the word "NACH" 331 | leds[66] = CRGB(color[1], color[0], color[2]); 332 | leds[67] = CRGB(color[1], color[0], color[2]); 333 | leds[68] = CRGB(color[1], color[0], color[2]); 334 | leds[69] = CRGB(color[1], color[0], color[2]); 335 | } 336 | 337 | void showWordFreya() { 338 | showUhrWord = false; 339 | //Light up the LEDs for the word "FREYA" 340 | leds[75] = CRGB(0, 255, 0); 341 | leds[76] = CRGB(0, 255, 0); 342 | leds[77] = CRGB(0, 255, 0); 343 | leds[78] = CRGB(0, 255, 0); 344 | leds[79] = CRGB(0, 255, 0); 345 | 346 | for (int i = 0; i < HEART_LEDS; i++) { 347 | leds[heartLEDs[i]] = CRGB(0, 255, 0); 348 | FastLED.delay(150); 349 | } 350 | delay(150); 351 | 352 | for (int i = 0; i < HEART_LEDS; i++) { 353 | leds[heartLEDs[i]] = CRGB(0, 0, 0); 354 | FastLED.delay(150); 355 | } 356 | showUhrWord = true; 357 | } 358 | 359 | void setColorForClockElement(ClockElement clockElement, int r, int g, int b) { 360 | for (int k = clockElement.GetRangeFrom(); k < clockElement.GetRangeTo(); k++) 361 | { 362 | leds[k] = CRGB(r, g, b); 363 | } 364 | } 365 | 366 | ClockElement findClockElementByNumericValueAndType(int numericValue, CLOCK_ELEMENT_TYPE elementType) { 367 | ClockElement *foundElement = NULL; 368 | 369 | for (int i = 0; i < NUM_CLOCK_ELEMENTS; i++) 370 | { 371 | ClockElement clockElement = timeClockElements[i]; 372 | 373 | if (elementType == MINUTE && clockElement.GetClockElementType() == MINUTE) { 374 | if ((numericValue == clockElement.GetNumericValueAM() || numericValue == clockElement.GetNumericValuePM())) { 375 | return timeClockElements[i]; 376 | } 377 | } else if (elementType == HOUR && clockElement.GetClockElementType() == HOUR) { 378 | if (numericValue == clockElement.GetNumericValueAM() || numericValue == clockElement.GetNumericValuePM()) { 379 | return timeClockElements[i]; 380 | } 381 | 382 | } 383 | } 384 | 385 | if (foundElement == NULL) { 386 | Serial.print("foundElement of type "); 387 | if (elementType == HOUR) { 388 | Serial.println("hour is NULL"); 389 | } else if (elementType == MINUTE) { 390 | Serial.println("minute is NULL"); 391 | } 392 | } 393 | 394 | return *foundElement; 395 | } 396 | -------------------------------------------------------------------------------- /word_clock/.flutter-plugins-dependencies: -------------------------------------------------------------------------------- 1 | {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"wifi","path":"/Users/felixseip/Documents/dev-tools/flutter/.pub-cache/hosted/pub.dartlang.org/wifi-0.1.5/","dependencies":[]}],"android":[{"name":"wifi","path":"/Users/felixseip/Documents/dev-tools/flutter/.pub-cache/hosted/pub.dartlang.org/wifi-0.1.5/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"wifi","dependencies":[]}],"date_created":"2020-07-10 11:11:26.923134","version":"1.17.5"} -------------------------------------------------------------------------------- /word_clock/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # Visual Studio Code related 20 | .vscode/ 21 | 22 | # Flutter/Dart/Pub related 23 | **/doc/api/ 24 | .dart_tool/ 25 | .flutter-plugins 26 | .packages 27 | .pub-cache/ 28 | .pub/ 29 | build/ 30 | 31 | # Android related 32 | **/android/**/gradle-wrapper.jar 33 | **/android/.gradle 34 | **/android/captures/ 35 | **/android/gradlew 36 | **/android/gradlew.bat 37 | **/android/local.properties 38 | **/android/**/GeneratedPluginRegistrant.java 39 | 40 | # iOS/XCode related 41 | **/ios/**/*.mode1v3 42 | **/ios/**/*.mode2v3 43 | **/ios/**/*.moved-aside 44 | **/ios/**/*.pbxuser 45 | **/ios/**/*.perspectivev3 46 | **/ios/**/*sync/ 47 | **/ios/**/.sconsign.dblite 48 | **/ios/**/.tags* 49 | **/ios/**/.vagrant/ 50 | **/ios/**/DerivedData/ 51 | **/ios/**/Icon? 52 | **/ios/**/Pods/ 53 | **/ios/**/.symlinks/ 54 | **/ios/**/profile 55 | **/ios/**/xcuserdata 56 | **/ios/.generated/ 57 | **/ios/Flutter/App.framework 58 | **/ios/Flutter/Flutter.framework 59 | **/ios/Flutter/Generated.xcconfig 60 | **/ios/Flutter/app.flx 61 | **/ios/Flutter/app.zip 62 | **/ios/Flutter/flutter_assets/ 63 | **/ios/ServiceDefinitions.json 64 | **/ios/Runner/GeneratedPluginRegistrant.* 65 | 66 | # Exceptions to above rules. 67 | !**/ios/**/default.mode1v3 68 | !**/ios/**/default.mode2v3 69 | !**/ios/**/default.pbxuser 70 | !**/ios/**/default.perspectivev3 71 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 72 | -------------------------------------------------------------------------------- /word_clock/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /word_clock/README.md: -------------------------------------------------------------------------------- 1 | # word_clock 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.io/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /word_clock/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.wordclock" 37 | minSdkVersion 21 38 | targetSdkVersion 27 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | -------------------------------------------------------------------------------- /word_clock/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 15 | 19 | 26 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /word_clock/android/app/src/main/java/com/example/wordclock/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.wordclock; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-hdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-hdpi/launcher_icon.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-mdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-mdpi/launcher_icon.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /word_clock/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /word_clock/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /word_clock/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /word_clock/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /word_clock/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /word_clock/assets/clock_element_indices.txt: -------------------------------------------------------------------------------- 1 | -10: 7,10 2 | -11: 11,14 3 | -12: 26,32 4 | -13: 15,21 5 | -1: 0,1 6 | -2: 3,5 7 | -3: 33,35 8 | -4: 44,47 9 | -5: 55,58 10 | -6: 118,120 11 | 1: 66,69 12 | 2: 73,76 13 | 3: 77,80 14 | 4: 84,87 15 | 5: 62,65 16 | 6: 88,92 17 | 7: 92,97 18 | 8: 99,102 19 | 9: 113,116 20 | 10: 110,113 21 | 11: 60,62 22 | 12: 103,107 -------------------------------------------------------------------------------- /word_clock/assets/clock_text.txt: -------------------------------------------------------------------------------- 1 | E S A I S T E F Ü N F Z E H N Z W A N Z I G M E N Ü V I E R T E L V O R S G N A Z F R E N A C H U N T A G Y A H A L B T E L F Ü N F E I N S E O K Z W E I D R E I N E S V I E R S E C H S I E B E N J A C H T Z W Ö L F E T Z E H N E U N A U H R -------------------------------------------------------------------------------- /word_clock/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/assets/icon.png -------------------------------------------------------------------------------- /word_clock/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/assets/logo.png -------------------------------------------------------------------------------- /word_clock/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 35 | 41 | 57 | 63 | 88 | 100 | 122 | 124 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /word_clock/assets/word-clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/assets/word-clock.png -------------------------------------------------------------------------------- /word_clock/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /word_clock/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /word_clock/ios/Flutter/Flutter.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: This podspec is NOT to be published. It is only used as a local source! 3 | # 4 | 5 | Pod::Spec.new do |s| 6 | s.name = 'Flutter' 7 | s.version = '1.0.0' 8 | s.summary = 'High-performance, high-fidelity mobile apps.' 9 | s.description = <<-DESC 10 | Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS. 11 | DESC 12 | s.homepage = 'https://flutter.io' 13 | s.license = { :type => 'MIT' } 14 | s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } 15 | s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } 16 | s.ios.deployment_target = '8.0' 17 | s.vendored_frameworks = 'Flutter.framework' 18 | end 19 | -------------------------------------------------------------------------------- /word_clock/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /word_clock/ios/Flutter/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=/Users/felixseip/Documents/dev-tools/flutter" 4 | export "FLUTTER_APPLICATION_PATH=/Users/felixseip/Documents/projects/99crafts/ArduinoWordClock/word_clock" 5 | export "FLUTTER_TARGET=/Users/felixseip/Documents/projects/99crafts/ArduinoWordClock/word_clock/lib/main.dart" 6 | export "FLUTTER_BUILD_DIR=build" 7 | export "SYMROOT=${SOURCE_ROOT}/../build/ios" 8 | export "OTHER_LDFLAGS=$(inherited) -framework Flutter" 9 | export "FLUTTER_FRAMEWORK_DIR=/Users/felixseip/Documents/dev-tools/flutter/bin/cache/artifacts/engine/ios" 10 | export "FLUTTER_BUILD_NAME=1.0.0" 11 | export "FLUTTER_BUILD_NUMBER=1" 12 | export "TRACK_WIDGET_CREATION=true" 13 | -------------------------------------------------------------------------------- /word_clock/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | # Flutter Pod 37 | 38 | copied_flutter_dir = File.join(__dir__, 'Flutter') 39 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 40 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 41 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 42 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 43 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 44 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 45 | 46 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 47 | unless File.exist?(generated_xcode_build_settings_path) 48 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 49 | end 50 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 51 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 52 | 53 | unless File.exist?(copied_framework_path) 54 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 55 | end 56 | unless File.exist?(copied_podspec_path) 57 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 58 | end 59 | end 60 | 61 | # Keep pod path relative so it can be checked into Podfile.lock. 62 | pod 'Flutter', :path => 'Flutter' 63 | 64 | # Plugin Pods 65 | 66 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 67 | # referring to absolute paths on developers' machines. 68 | system('rm -rf .symlinks') 69 | system('mkdir -p .symlinks/plugins') 70 | plugin_pods = parse_KV_file('../.flutter-plugins') 71 | plugin_pods.each do |name, path| 72 | symlink = File.join('.symlinks', 'plugins', name) 73 | File.symlink(path, symlink) 74 | pod name, :path => File.join(symlink, 'ios') 75 | end 76 | end 77 | 78 | post_install do |installer| 79 | installer.pods_project.targets.each do |target| 80 | target.build_configurations.each do |config| 81 | config.build_settings['ENABLE_BITCODE'] = 'NO' 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /word_clock/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 13 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 14 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 18 | B326898760509BF1A5024B53 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 945069F5AB3FEE99E9309788 /* libPods-Runner.a */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXCopyFilesBuildPhase section */ 22 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 23 | isa = PBXCopyFilesBuildPhase; 24 | buildActionMask = 2147483647; 25 | dstPath = ""; 26 | dstSubfolderSpec = 10; 27 | files = ( 28 | ); 29 | name = "Embed Frameworks"; 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXCopyFilesBuildPhase section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 36 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 37 | 33F0238B22F74314A53CCB35 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 38 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 39 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 40 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 41 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 42 | 945069F5AB3FEE99E9309788 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 44 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 45 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 48 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 49 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 50 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | A9FF58503EDA3EC92907AF45 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 52 | F10705CE61F6C2F87B716D64 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | B326898760509BF1A5024B53 /* libPods-Runner.a in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 3A2C1A2D90082831D345B685 /* Frameworks */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 945069F5AB3FEE99E9309788 /* libPods-Runner.a */, 71 | ); 72 | name = Frameworks; 73 | sourceTree = ""; 74 | }; 75 | 6355EBDE2C75FB5FC8F7159F /* Pods */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | A9FF58503EDA3EC92907AF45 /* Pods-Runner.debug.xcconfig */, 79 | F10705CE61F6C2F87B716D64 /* Pods-Runner.release.xcconfig */, 80 | 33F0238B22F74314A53CCB35 /* Pods-Runner.profile.xcconfig */, 81 | ); 82 | path = Pods; 83 | sourceTree = ""; 84 | }; 85 | 9740EEB11CF90186004384FC /* Flutter */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 89 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 90 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 91 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 92 | ); 93 | name = Flutter; 94 | sourceTree = ""; 95 | }; 96 | 97C146E51CF9000F007C117D = { 97 | isa = PBXGroup; 98 | children = ( 99 | 9740EEB11CF90186004384FC /* Flutter */, 100 | 97C146F01CF9000F007C117D /* Runner */, 101 | 97C146EF1CF9000F007C117D /* Products */, 102 | 6355EBDE2C75FB5FC8F7159F /* Pods */, 103 | 3A2C1A2D90082831D345B685 /* Frameworks */, 104 | ); 105 | sourceTree = ""; 106 | }; 107 | 97C146EF1CF9000F007C117D /* Products */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 97C146EE1CF9000F007C117D /* Runner.app */, 111 | ); 112 | name = Products; 113 | sourceTree = ""; 114 | }; 115 | 97C146F01CF9000F007C117D /* Runner */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 119 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 120 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 121 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 122 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 123 | 97C147021CF9000F007C117D /* Info.plist */, 124 | 97C146F11CF9000F007C117D /* Supporting Files */, 125 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 126 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 127 | ); 128 | path = Runner; 129 | sourceTree = ""; 130 | }; 131 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 97C146F21CF9000F007C117D /* main.m */, 135 | ); 136 | name = "Supporting Files"; 137 | sourceTree = ""; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXNativeTarget section */ 142 | 97C146ED1CF9000F007C117D /* Runner */ = { 143 | isa = PBXNativeTarget; 144 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 145 | buildPhases = ( 146 | 9F636002125951E21142CF63 /* [CP] Check Pods Manifest.lock */, 147 | 9740EEB61CF901F6004384FC /* Run Script */, 148 | 97C146EA1CF9000F007C117D /* Sources */, 149 | 97C146EB1CF9000F007C117D /* Frameworks */, 150 | 97C146EC1CF9000F007C117D /* Resources */, 151 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 152 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 153 | C56720924C36059C907603F3 /* [CP] Embed Pods Frameworks */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | ); 159 | name = Runner; 160 | productName = Runner; 161 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 162 | productType = "com.apple.product-type.application"; 163 | }; 164 | /* End PBXNativeTarget section */ 165 | 166 | /* Begin PBXProject section */ 167 | 97C146E61CF9000F007C117D /* Project object */ = { 168 | isa = PBXProject; 169 | attributes = { 170 | LastUpgradeCheck = 0910; 171 | ORGANIZATIONNAME = "The Chromium Authors"; 172 | TargetAttributes = { 173 | 97C146ED1CF9000F007C117D = { 174 | CreatedOnToolsVersion = 7.3.1; 175 | DevelopmentTeam = M5CXW84U3N; 176 | }; 177 | }; 178 | }; 179 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 180 | compatibilityVersion = "Xcode 3.2"; 181 | developmentRegion = English; 182 | hasScannedForEncodings = 0; 183 | knownRegions = ( 184 | English, 185 | en, 186 | Base, 187 | ); 188 | mainGroup = 97C146E51CF9000F007C117D; 189 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 190 | projectDirPath = ""; 191 | projectRoot = ""; 192 | targets = ( 193 | 97C146ED1CF9000F007C117D /* Runner */, 194 | ); 195 | }; 196 | /* End PBXProject section */ 197 | 198 | /* Begin PBXResourcesBuildPhase section */ 199 | 97C146EC1CF9000F007C117D /* Resources */ = { 200 | isa = PBXResourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 204 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 205 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 206 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 207 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXResourcesBuildPhase section */ 212 | 213 | /* Begin PBXShellScriptBuildPhase section */ 214 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 215 | isa = PBXShellScriptBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | ); 219 | inputPaths = ( 220 | ); 221 | name = "Thin Binary"; 222 | outputPaths = ( 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | shellPath = /bin/sh; 226 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n"; 227 | }; 228 | 9740EEB61CF901F6004384FC /* Run Script */ = { 229 | isa = PBXShellScriptBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | ); 233 | inputPaths = ( 234 | ); 235 | name = "Run Script"; 236 | outputPaths = ( 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | shellPath = /bin/sh; 240 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 241 | }; 242 | 9F636002125951E21142CF63 /* [CP] Check Pods Manifest.lock */ = { 243 | isa = PBXShellScriptBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | ); 247 | inputFileListPaths = ( 248 | ); 249 | inputPaths = ( 250 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 251 | "${PODS_ROOT}/Manifest.lock", 252 | ); 253 | name = "[CP] Check Pods Manifest.lock"; 254 | outputFileListPaths = ( 255 | ); 256 | outputPaths = ( 257 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | shellPath = /bin/sh; 261 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 262 | showEnvVarsInLog = 0; 263 | }; 264 | C56720924C36059C907603F3 /* [CP] Embed Pods Frameworks */ = { 265 | isa = PBXShellScriptBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | ); 269 | inputPaths = ( 270 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", 271 | "${PODS_ROOT}/../Flutter/Flutter.framework", 272 | ); 273 | name = "[CP] Embed Pods Frameworks"; 274 | outputPaths = ( 275 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | shellPath = /bin/sh; 279 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 280 | showEnvVarsInLog = 0; 281 | }; 282 | /* End PBXShellScriptBuildPhase section */ 283 | 284 | /* Begin PBXSourcesBuildPhase section */ 285 | 97C146EA1CF9000F007C117D /* Sources */ = { 286 | isa = PBXSourcesBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 290 | 97C146F31CF9000F007C117D /* main.m in Sources */, 291 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXSourcesBuildPhase section */ 296 | 297 | /* Begin PBXVariantGroup section */ 298 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 299 | isa = PBXVariantGroup; 300 | children = ( 301 | 97C146FB1CF9000F007C117D /* Base */, 302 | ); 303 | name = Main.storyboard; 304 | sourceTree = ""; 305 | }; 306 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 307 | isa = PBXVariantGroup; 308 | children = ( 309 | 97C147001CF9000F007C117D /* Base */, 310 | ); 311 | name = LaunchScreen.storyboard; 312 | sourceTree = ""; 313 | }; 314 | /* End PBXVariantGroup section */ 315 | 316 | /* Begin XCBuildConfiguration section */ 317 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 318 | isa = XCBuildConfiguration; 319 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 320 | buildSettings = { 321 | ALWAYS_SEARCH_USER_PATHS = NO; 322 | CLANG_ANALYZER_NONNULL = YES; 323 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 324 | CLANG_CXX_LIBRARY = "libc++"; 325 | CLANG_ENABLE_MODULES = YES; 326 | CLANG_ENABLE_OBJC_ARC = YES; 327 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 328 | CLANG_WARN_BOOL_CONVERSION = YES; 329 | CLANG_WARN_COMMA = YES; 330 | CLANG_WARN_CONSTANT_CONVERSION = YES; 331 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 332 | CLANG_WARN_EMPTY_BODY = YES; 333 | CLANG_WARN_ENUM_CONVERSION = YES; 334 | CLANG_WARN_INFINITE_RECURSION = YES; 335 | CLANG_WARN_INT_CONVERSION = YES; 336 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 337 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 338 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 339 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 340 | CLANG_WARN_STRICT_PROTOTYPES = YES; 341 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 342 | CLANG_WARN_UNREACHABLE_CODE = YES; 343 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 344 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 345 | COPY_PHASE_STRIP = NO; 346 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 347 | ENABLE_NS_ASSERTIONS = NO; 348 | ENABLE_STRICT_OBJC_MSGSEND = YES; 349 | GCC_C_LANGUAGE_STANDARD = gnu99; 350 | GCC_NO_COMMON_BLOCKS = YES; 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 358 | MTL_ENABLE_DEBUG_INFO = NO; 359 | SDKROOT = iphoneos; 360 | TARGETED_DEVICE_FAMILY = "1,2"; 361 | VALIDATE_PRODUCT = YES; 362 | }; 363 | name = Profile; 364 | }; 365 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 366 | isa = XCBuildConfiguration; 367 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 368 | buildSettings = { 369 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 370 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 371 | DEVELOPMENT_TEAM = M5CXW84U3N; 372 | ENABLE_BITCODE = NO; 373 | FRAMEWORK_SEARCH_PATHS = ( 374 | "$(inherited)", 375 | "$(PROJECT_DIR)/Flutter", 376 | ); 377 | INFOPLIST_FILE = Runner/Info.plist; 378 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 379 | LIBRARY_SEARCH_PATHS = ( 380 | "$(inherited)", 381 | "$(PROJECT_DIR)/Flutter", 382 | ); 383 | PRODUCT_BUNDLE_IDENTIFIER = com.99crafts.wordclock; 384 | PRODUCT_NAME = "$(TARGET_NAME)"; 385 | VERSIONING_SYSTEM = "apple-generic"; 386 | }; 387 | name = Profile; 388 | }; 389 | 97C147031CF9000F007C117D /* Debug */ = { 390 | isa = XCBuildConfiguration; 391 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 392 | buildSettings = { 393 | ALWAYS_SEARCH_USER_PATHS = NO; 394 | CLANG_ANALYZER_NONNULL = YES; 395 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 396 | CLANG_CXX_LIBRARY = "libc++"; 397 | CLANG_ENABLE_MODULES = YES; 398 | CLANG_ENABLE_OBJC_ARC = YES; 399 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 400 | CLANG_WARN_BOOL_CONVERSION = YES; 401 | CLANG_WARN_COMMA = YES; 402 | CLANG_WARN_CONSTANT_CONVERSION = YES; 403 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 404 | CLANG_WARN_EMPTY_BODY = YES; 405 | CLANG_WARN_ENUM_CONVERSION = YES; 406 | CLANG_WARN_INFINITE_RECURSION = YES; 407 | CLANG_WARN_INT_CONVERSION = YES; 408 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 409 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 411 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 412 | CLANG_WARN_STRICT_PROTOTYPES = YES; 413 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 414 | CLANG_WARN_UNREACHABLE_CODE = YES; 415 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 416 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 417 | COPY_PHASE_STRIP = NO; 418 | DEBUG_INFORMATION_FORMAT = dwarf; 419 | ENABLE_STRICT_OBJC_MSGSEND = YES; 420 | ENABLE_TESTABILITY = YES; 421 | GCC_C_LANGUAGE_STANDARD = gnu99; 422 | GCC_DYNAMIC_NO_PIC = NO; 423 | GCC_NO_COMMON_BLOCKS = YES; 424 | GCC_OPTIMIZATION_LEVEL = 0; 425 | GCC_PREPROCESSOR_DEFINITIONS = ( 426 | "DEBUG=1", 427 | "$(inherited)", 428 | ); 429 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 430 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 431 | GCC_WARN_UNDECLARED_SELECTOR = YES; 432 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 433 | GCC_WARN_UNUSED_FUNCTION = YES; 434 | GCC_WARN_UNUSED_VARIABLE = YES; 435 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 436 | MTL_ENABLE_DEBUG_INFO = YES; 437 | ONLY_ACTIVE_ARCH = YES; 438 | SDKROOT = iphoneos; 439 | TARGETED_DEVICE_FAMILY = "1,2"; 440 | }; 441 | name = Debug; 442 | }; 443 | 97C147041CF9000F007C117D /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 446 | buildSettings = { 447 | ALWAYS_SEARCH_USER_PATHS = NO; 448 | CLANG_ANALYZER_NONNULL = YES; 449 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 450 | CLANG_CXX_LIBRARY = "libc++"; 451 | CLANG_ENABLE_MODULES = YES; 452 | CLANG_ENABLE_OBJC_ARC = YES; 453 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 454 | CLANG_WARN_BOOL_CONVERSION = YES; 455 | CLANG_WARN_COMMA = YES; 456 | CLANG_WARN_CONSTANT_CONVERSION = YES; 457 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 458 | CLANG_WARN_EMPTY_BODY = YES; 459 | CLANG_WARN_ENUM_CONVERSION = YES; 460 | CLANG_WARN_INFINITE_RECURSION = YES; 461 | CLANG_WARN_INT_CONVERSION = YES; 462 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 463 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 464 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 465 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 466 | CLANG_WARN_STRICT_PROTOTYPES = YES; 467 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 468 | CLANG_WARN_UNREACHABLE_CODE = YES; 469 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 470 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 471 | COPY_PHASE_STRIP = NO; 472 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 473 | ENABLE_NS_ASSERTIONS = NO; 474 | ENABLE_STRICT_OBJC_MSGSEND = YES; 475 | GCC_C_LANGUAGE_STANDARD = gnu99; 476 | GCC_NO_COMMON_BLOCKS = YES; 477 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 478 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 479 | GCC_WARN_UNDECLARED_SELECTOR = YES; 480 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 481 | GCC_WARN_UNUSED_FUNCTION = YES; 482 | GCC_WARN_UNUSED_VARIABLE = YES; 483 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 484 | MTL_ENABLE_DEBUG_INFO = NO; 485 | SDKROOT = iphoneos; 486 | TARGETED_DEVICE_FAMILY = "1,2"; 487 | VALIDATE_PRODUCT = YES; 488 | }; 489 | name = Release; 490 | }; 491 | 97C147061CF9000F007C117D /* Debug */ = { 492 | isa = XCBuildConfiguration; 493 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 494 | buildSettings = { 495 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 496 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 497 | DEVELOPMENT_TEAM = M5CXW84U3N; 498 | ENABLE_BITCODE = NO; 499 | FRAMEWORK_SEARCH_PATHS = ( 500 | "$(inherited)", 501 | "$(PROJECT_DIR)/Flutter", 502 | ); 503 | INFOPLIST_FILE = Runner/Info.plist; 504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 505 | LIBRARY_SEARCH_PATHS = ( 506 | "$(inherited)", 507 | "$(PROJECT_DIR)/Flutter", 508 | ); 509 | PRODUCT_BUNDLE_IDENTIFIER = com.99crafts.wordclock; 510 | PRODUCT_NAME = "$(TARGET_NAME)"; 511 | VERSIONING_SYSTEM = "apple-generic"; 512 | }; 513 | name = Debug; 514 | }; 515 | 97C147071CF9000F007C117D /* Release */ = { 516 | isa = XCBuildConfiguration; 517 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 518 | buildSettings = { 519 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 520 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 521 | DEVELOPMENT_TEAM = M5CXW84U3N; 522 | ENABLE_BITCODE = NO; 523 | FRAMEWORK_SEARCH_PATHS = ( 524 | "$(inherited)", 525 | "$(PROJECT_DIR)/Flutter", 526 | ); 527 | INFOPLIST_FILE = Runner/Info.plist; 528 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 529 | LIBRARY_SEARCH_PATHS = ( 530 | "$(inherited)", 531 | "$(PROJECT_DIR)/Flutter", 532 | ); 533 | PRODUCT_BUNDLE_IDENTIFIER = com.99crafts.wordclock; 534 | PRODUCT_NAME = "$(TARGET_NAME)"; 535 | VERSIONING_SYSTEM = "apple-generic"; 536 | }; 537 | name = Release; 538 | }; 539 | /* End XCBuildConfiguration section */ 540 | 541 | /* Begin XCConfigurationList section */ 542 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 543 | isa = XCConfigurationList; 544 | buildConfigurations = ( 545 | 97C147031CF9000F007C117D /* Debug */, 546 | 97C147041CF9000F007C117D /* Release */, 547 | 249021D3217E4FDB00AE95B9 /* Profile */, 548 | ); 549 | defaultConfigurationIsVisible = 0; 550 | defaultConfigurationName = Release; 551 | }; 552 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 553 | isa = XCConfigurationList; 554 | buildConfigurations = ( 555 | 97C147061CF9000F007C117D /* Debug */, 556 | 97C147071CF9000F007C117D /* Release */, 557 | 249021D4217E4FDB00AE95B9 /* Profile */, 558 | ); 559 | defaultConfigurationIsVisible = 0; 560 | defaultConfigurationName = Release; 561 | }; 562 | /* End XCConfigurationList section */ 563 | }; 564 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 565 | } 566 | -------------------------------------------------------------------------------- /word_clock/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /word_clock/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /word_clock/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /word_clock/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /word_clock/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /word_clock/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /word_clock/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /word_clock/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Felix-Seip/ArduinoWordClock/0939a3dc0c871b404553e8c0c0261efa7c595ef3/word_clock/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /word_clock/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /word_clock/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /word_clock/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /word_clock/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Word Clock 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | word_clock 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 2 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 5 25 | LSRequiresIPhoneOS 26 | 27 | NSBluetoothPeripheralUsageDescription 28 | Bluetooth is required to connect to your 99 crafts word clock. Once connected to the word clock, you can change the color of the LEDs and set the time of the clock, using bluetooth. 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /word_clock/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /word_clock/lib/clocks/clock_rest_commands.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:convert'; 3 | import 'dart:io'; 4 | 5 | import 'package:http/http.dart' as http; 6 | 7 | abstract class ClockRestCommands { 8 | String ip; 9 | http.Client client; 10 | 11 | void sendClockCommand(final String restPath, final String param) async { 12 | try { 13 | final response = 14 | await client.get(Uri.parse('http://$ip/$restPath?param=$param')); 15 | 16 | switch (response.statusCode) { 17 | case 200: 18 | if (!response.body.startsWith("<")) { 19 | json.decode(response.body); 20 | } 21 | break; 22 | case 404: 23 | break; 24 | default: 25 | } 26 | } on SocketException catch (e) { 27 | //NOP 28 | } 29 | } 30 | 31 | void changeBrightness( 32 | final double brightness, 33 | ) { 34 | String brightnessCommand = "$brightness"; 35 | sendClockCommand("clockbrightness", brightnessCommand); 36 | } 37 | 38 | void setTime( 39 | final TimeOfDay time, 40 | ) { 41 | String timeCommand = "${time.hour},${time.minute}"; 42 | sendClockCommand("clocktime", timeCommand); 43 | } 44 | 45 | void setLEDColor( 46 | final int r, 47 | final int g, 48 | final int b, 49 | ) { 50 | String colorCommand = "$r,$g,$b"; 51 | sendClockCommand("clockcolor", colorCommand); 52 | } 53 | 54 | void configureClock( 55 | final String wifiSSID, 56 | final String wifiPassword, 57 | final String clockRoom, 58 | ) { 59 | String configureCommand = 60 | "ssid=$wifiSSID,password=$wifiPassword,room-name=$clockRoom"; 61 | sendClockCommand("clockconfiguration", configureCommand); 62 | } 63 | 64 | void changeClockName( 65 | final String clockName, 66 | ) { 67 | String clockNameCommand = "$clockName"; 68 | sendClockCommand("clockname", clockNameCommand); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /word_clock/lib/clocks/word_clock/word_clock_rest_commands.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/http.dart' as http; 2 | 3 | import '../clock_rest_commands.dart'; 4 | 5 | class WordClockRestCommands extends ClockRestCommands { 6 | WordClockRestCommands(String _ip) { 7 | super.ip = _ip; 8 | super.client = http.Client(); 9 | } 10 | 11 | void showFreya() { 12 | sendClockCommand("wordclockfreya", ""); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /word_clock/lib/dialogs/clock_configuration_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ClockConfigurationDialog extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Dialog( 7 | shape: RoundedRectangleBorder( 8 | borderRadius: BorderRadius.circular(8.0), 9 | ), 10 | child: Container( 11 | height: 220.0, 12 | width: 300.0, 13 | child: Column( 14 | children: [ 15 | Container( 16 | alignment: Alignment.topLeft, 17 | width: 300, 18 | decoration: BoxDecoration( 19 | borderRadius: BorderRadius.only( 20 | topLeft: Radius.circular(8), 21 | topRight: Radius.circular(8), 22 | ), 23 | color: Color.fromARGB(255, 10, 9, 8), 24 | ), 25 | child: Padding( 26 | child: Text( 27 | "Edit Clock Configuration", 28 | style: TextStyle( 29 | color: Color.fromARGB(255, 242, 244, 243), 30 | fontSize: 18, 31 | ), 32 | ), 33 | padding: EdgeInsets.all(22), 34 | ), 35 | ), 36 | Expanded( 37 | child: Padding( 38 | child: TextField( 39 | decoration: InputDecoration( 40 | hintText: "Uhr Name", 41 | ), 42 | ), 43 | padding: EdgeInsets.all(30), 44 | ), 45 | ), 46 | ], 47 | ), 48 | ), 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /word_clock/lib/dialogs/color_picker_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_colorpicker/flutter_colorpicker.dart'; 3 | 4 | class ColorPickerDialog extends StatefulWidget { 5 | final Function _changeClockColor; 6 | 7 | ColorPickerDialog(this._changeClockColor); 8 | 9 | @override 10 | _ColorPickerDialogState createState() => _ColorPickerDialogState(); 11 | } 12 | 13 | class _ColorPickerDialogState extends State { 14 | Color currentColor = Colors.black; 15 | 16 | void changeColor(Color color) { 17 | widget._changeClockColor( 18 | color.red, 19 | color.green, 20 | color.blue, 21 | ); 22 | } 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return Dialog( 27 | shape: RoundedRectangleBorder( 28 | borderRadius: BorderRadius.circular(16.0), 29 | ), 30 | child: Container( 31 | child: SingleChildScrollView( 32 | //physics: const NeverScrollableScrollPhysics(), 33 | padding: EdgeInsets.all(25), 34 | child: BlockPicker( 35 | //availableColors: [Colors.red, Colors.black, Colors.blue], 36 | pickerColor: currentColor, 37 | onColorChanged: changeColor, 38 | availableColors: [ 39 | Color.fromARGB( 40 | 255, 41 | 235, 42 | 52, 43 | 35, 44 | ), 45 | Color.fromARGB( 46 | 255, 47 | 238, 48 | 98, 49 | 42, 50 | ), 51 | Color.fromARGB( 52 | 255, 53 | 244, 54 | 177, 55 | 62, 56 | ), 57 | Color.fromARGB( 58 | 255, 59 | 254, 60 | 252, 61 | 83, 62 | ), 63 | Color.fromARGB( 64 | 255, 65 | 186, 66 | 250, 67 | 80, 68 | ), 69 | Color.fromARGB( 70 | 255, 71 | 117, 72 | 249, 73 | 76, 74 | ), 75 | Color.fromARGB( 76 | 255, 77 | 116, 78 | 249, 79 | 182, 80 | ), 81 | Color.fromARGB( 82 | 255, 83 | 82, 84 | 249, 85 | 182, 86 | ), 87 | Color.fromARGB( 88 | 255, 89 | 0, 90 | 41, 91 | 245, 92 | ), 93 | Color.fromARGB( 94 | 255, 95 | 228, 96 | 64, 97 | 247, 98 | ), 99 | Color.fromARGB( 100 | 255, 101 | 235, 102 | 56, 103 | 153, 104 | ), 105 | Color.fromARGB( 106 | 255, 107 | 230, 108 | 230, 109 | 230, 110 | ), 111 | ], 112 | ), 113 | ), 114 | ), 115 | ); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /word_clock/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:async'; 3 | 4 | import './screens/splash_screen.dart'; 5 | import './screens/main_screen.dart'; 6 | 7 | void main() => runApp(MyApp()); 8 | 9 | class MyApp extends StatefulWidget { 10 | @override 11 | _MyApp createState() => _MyApp(); 12 | } 13 | 14 | class _MyApp extends State { 15 | bool _isPastSplashScreen = false; 16 | 17 | static const int splashScreenTimeout = 6; 18 | 19 | @override 20 | void initState() { 21 | super.initState(); 22 | _startSplashScreenTimer(); 23 | } 24 | 25 | // This widget is the root of your application. 26 | @override 27 | Widget build(BuildContext context) { 28 | return MaterialApp( 29 | theme: ThemeData( 30 | primaryColor: Color.fromARGB(255, 94, 80, 63), 31 | accentColor: Color.fromARGB(255, 94, 80, 63), 32 | ), 33 | home: Scaffold( 34 | body: !_isPastSplashScreen ? SplashScreen() : MainScreen(), 35 | ), 36 | ); 37 | } 38 | 39 | _startSplashScreenTimer() { 40 | Timer(Duration(seconds: splashScreenTimeout), () { 41 | setState(() { 42 | _isPastSplashScreen = true; 43 | }); 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /word_clock/lib/model/clock.dart: -------------------------------------------------------------------------------- 1 | class Clock { 2 | final String clockType; 3 | final String ipAddress; 4 | final String roomName; 5 | 6 | Clock(this.clockType, this.ipAddress, this.roomName); 7 | } 8 | -------------------------------------------------------------------------------- /word_clock/lib/screens/configuration_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../clocks/word_clock/word_clock_rest_commands.dart'; 4 | import '../widgets/configuration_item.dart'; 5 | 6 | class ConfigurationScreen extends StatefulWidget { 7 | final WordClockRestCommands _commands = WordClockRestCommands("192.168.4.1"); 8 | 9 | @override 10 | _ConfigurationScreenState createState() => _ConfigurationScreenState(); 11 | } 12 | 13 | class _ConfigurationScreenState extends State { 14 | String _wifiSSID; 15 | String _wifiPassword; 16 | String _clockName; 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | } 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return Scaffold( 26 | appBar: AppBar( 27 | title: Text('Uhrkonfiguration'), 28 | backgroundColor: Color.fromARGB(255, 10, 9, 8), 29 | ), 30 | backgroundColor: Color.fromARGB(255, 242, 244, 243), 31 | body: Padding( 32 | padding: EdgeInsets.all(50), 33 | child: Column( 34 | crossAxisAlignment: CrossAxisAlignment.center, 35 | mainAxisAlignment: MainAxisAlignment.center, 36 | children: [ 37 | ConfigurationItem("WLAN Name", (String text) { 38 | _wifiSSID = text; 39 | }, EdgeInsets.all(10)), 40 | ConfigurationItem("WLAN Passwort", (String text) { 41 | _wifiPassword = text; 42 | }, EdgeInsets.all(10)), 43 | ConfigurationItem("Uhr Name", (String text) { 44 | _clockName = text; 45 | }, EdgeInsets.all(10)), 46 | Padding( 47 | padding: EdgeInsets.only(top: 20), 48 | child: Text( 49 | "Um eine neue Uhr zu konfigurieren, stellen Sie bitte sicher dass Sie mit dem WLAN von der Uhr verbunden sind. Nur so ist eine Konfiguration der Uhr möglich.", 50 | style: TextStyle( 51 | fontSize: 16, 52 | color: Color.fromARGB(100, 0, 0, 0), 53 | ), 54 | textAlign: TextAlign.center, 55 | ), 56 | ), 57 | ], 58 | ), 59 | ), 60 | floatingActionButton: FloatingActionButton( 61 | child: Icon(Icons.check), 62 | onPressed: () { 63 | widget._commands.configureClock(_wifiSSID, _wifiPassword, _clockName); 64 | }, 65 | ), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /word_clock/lib/screens/home_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../dialogs/color_picker_dialog.dart'; 3 | import 'package:flutter/services.dart' show rootBundle; 4 | import 'package:flutter/cupertino.dart'; 5 | 6 | import 'package:word_clock/widgets/clocks/word_clock/word_clock.dart'; 7 | import '../clocks/word_clock/word_clock_rest_commands.dart'; 8 | import 'dart:async'; 9 | import '../dialogs/clock_configuration_dialog.dart'; 10 | 11 | ///Class to display the main screen of the app. 12 | class HomeScreen extends StatefulWidget { 13 | final String _ipAddress; 14 | final String _clockName; 15 | 16 | WordClockRestCommands _wordClockRestCommands; 17 | 18 | HomeScreen(this._ipAddress, this._clockName) { 19 | this._wordClockRestCommands = WordClockRestCommands(_ipAddress); 20 | } 21 | 22 | @override 23 | _HomeScreenState createState() => _HomeScreenState(); 24 | } 25 | 26 | class _HomeScreenState extends State { 27 | Color currentColor = Color.fromARGB(255, 0, 0, 0); 28 | 29 | ///Loads the clock letters the file "assets/clock_text.txt" 30 | ///Load the clock letters to be displayed on the main screen. 31 | ///These letters are used as a preview for the actual word clock. 32 | Future> _loadClockLetters() { 33 | return rootBundle 34 | .loadString('assets/clock_text.txt') 35 | .then((String contents) { 36 | return contents.split(" "); 37 | }); 38 | } 39 | 40 | void changeClockConfiguration() { 41 | showDialog( 42 | context: context, 43 | builder: (BuildContext context) { 44 | return ClockConfigurationDialog(); 45 | }, 46 | ); 47 | } 48 | 49 | int _tapCount = 1; 50 | double _sliderValue = 255; 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return Scaffold( 55 | appBar: AppBar( 56 | title: Text('Word Clock @ ${widget._clockName}'), 57 | backgroundColor: Color.fromARGB(255, 10, 9, 8), 58 | actions: [ 59 | IconButton( 60 | icon: Icon(Icons.color_lens), 61 | tooltip: 'Change LED color', 62 | onPressed: () { 63 | showDialog( 64 | context: context, 65 | builder: (BuildContext context) { 66 | return ColorPickerDialog( 67 | widget._wordClockRestCommands.setLEDColor); 68 | }, 69 | ); 70 | }, 71 | ), 72 | IconButton( 73 | icon: Icon(Icons.edit), 74 | tooltip: 'Change clock configuration', 75 | onPressed: () { 76 | changeClockConfiguration(); 77 | }, 78 | ), 79 | ], 80 | ), 81 | backgroundColor: Color.fromARGB(255, 242, 244, 243), 82 | body: new FutureBuilder>( 83 | future: _loadClockLetters(), // a Future or null 84 | builder: (BuildContext context, AsyncSnapshot> snapshot) { 85 | if (snapshot.hasData) { 86 | return Column( 87 | children: [ 88 | Expanded( 89 | child: GestureDetector( 90 | onTap: () { 91 | if (_tapCount == 1) { 92 | Timer(Duration(seconds: 10), () { 93 | if (!(_tapCount >= 10)) { 94 | _tapCount = 1; 95 | } 96 | }); 97 | } 98 | _tapCount++; 99 | if (_tapCount == 10) { 100 | print("show freya"); 101 | widget._wordClockRestCommands.showFreya(); 102 | _tapCount = 1; 103 | } 104 | }, 105 | child: WordClock( 106 | snapshot.data, 107 | currentColor, 108 | true, 109 | ), 110 | ), 111 | ), 112 | Padding( 113 | padding: EdgeInsets.only(bottom: 100, left: 40, right: 40), 114 | child: Column( 115 | children: [ 116 | Slider( 117 | activeColor: Colors.indigoAccent, 118 | min: 10.0, 119 | max: 255.0, 120 | label: "Set brightness", 121 | onChanged: (newValue) { 122 | setState(() { 123 | _sliderValue = newValue; 124 | }); 125 | }, 126 | onChangeEnd: (brightness) { 127 | widget._wordClockRestCommands 128 | .changeBrightness(brightness); 129 | }, 130 | value: _sliderValue, 131 | ), 132 | ], 133 | ), 134 | ), 135 | ], 136 | ); 137 | } else { 138 | return new Container( 139 | child: CircularProgressIndicator( 140 | valueColor: new AlwaysStoppedAnimation( 141 | Colors.black, 142 | ), 143 | ), 144 | ); 145 | } 146 | }, 147 | ), 148 | ); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /word_clock/lib/screens/main_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import './select_clock.dart'; 4 | import './configuration_screen.dart'; 5 | 6 | class MainScreen extends StatefulWidget { 7 | @override 8 | _MainScreenState createState() => _MainScreenState(); 9 | } 10 | 11 | class _MainScreenState extends State { 12 | int _currentIndex = 0; 13 | final List _children = [ 14 | SelectClock(), 15 | ConfigurationScreen(), 16 | ]; 17 | 18 | void onTabTapped(int index) { 19 | setState(() { 20 | _currentIndex = index; 21 | }); 22 | } 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return Scaffold( 27 | body: _children[_currentIndex], 28 | bottomNavigationBar: BottomNavigationBar( 29 | onTap: onTabTapped, 30 | currentIndex: _currentIndex, 31 | items: [ 32 | BottomNavigationBarItem( 33 | icon: new Icon( 34 | Icons.home, 35 | ), 36 | title: new Text('Auswählen'), 37 | ), 38 | BottomNavigationBarItem( 39 | icon: new Icon( 40 | Icons.add, 41 | ), 42 | title: new Text('Konfigurieren'), 43 | ), 44 | ], 45 | ), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /word_clock/lib/screens/select_clock.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../util/device_scanner.dart'; 3 | import 'dart:async'; 4 | 5 | import '../model/clock.dart'; 6 | import '../widgets/clock_list/clock_list.dart'; 7 | 8 | class SelectClock extends StatefulWidget { 9 | @override 10 | _SelectClockState createState() => _SelectClockState(); 11 | } 12 | 13 | class _SelectClockState extends State { 14 | final GlobalKey _refreshIndicatorKey = 15 | new GlobalKey(); 16 | List _clocks = []; 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | //_clocks.add(Clock("word-clock", "192.168.2.147", "Bedroom")); 22 | } 23 | 24 | Future _scanDevices() { 25 | return DeviceScanner.scanDevicesInLocalNetwork().then( 26 | (clocks) { 27 | setState(() { 28 | _clocks.addAll(clocks); 29 | }); 30 | }, 31 | ); 32 | } 33 | 34 | @override 35 | Widget build(BuildContext context) { 36 | return Scaffold( 37 | appBar: AppBar( 38 | title: Text('99Crafts Uhren'), 39 | backgroundColor: Color.fromARGB(255, 10, 9, 8), 40 | actions: [ 41 | IconButton( 42 | icon: Icon(Icons.refresh), 43 | tooltip: 'Refresh list of clocks', 44 | onPressed: () { 45 | _refreshIndicatorKey.currentState.show(); 46 | _scanDevices(); 47 | }, 48 | ), 49 | ], 50 | ), 51 | backgroundColor: Color.fromARGB(255, 242, 244, 243), 52 | body: RefreshIndicator( 53 | key: _refreshIndicatorKey, 54 | onRefresh: _scanDevices, 55 | child: _clocks.length == 0 56 | ? Padding( 57 | padding: EdgeInsets.all(50), 58 | child: Stack( 59 | children: [ 60 | Center( 61 | child: Text( 62 | "Es wurden keine 99 Crafts Uhren gefunden. Bitte stellen Sie sicher dass Sie mit einem WLAN Netzwerk verbunden sind und dass sich 99 Crafts Uhren in dem Netzwerk befinden.", 63 | style: TextStyle( 64 | fontSize: 16, 65 | color: Color.fromARGB(100, 0, 0, 0), 66 | ), 67 | textAlign: TextAlign.center, 68 | ), 69 | ), 70 | ], 71 | ), 72 | ) 73 | : ClockList(_clocks), 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /word_clock/lib/screens/splash_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | 4 | class SplashScreen extends StatefulWidget { 5 | SplashScreen(); 6 | 7 | @override 8 | _SplashScreenState createState() => _SplashScreenState(); 9 | } 10 | 11 | class _SplashScreenState extends State { 12 | bool _visible = false; 13 | 14 | @override 15 | void initState() { 16 | super.initState(); 17 | WidgetsBinding.instance.addPostFrameCallback( 18 | (_) => setState( 19 | () { 20 | _visible = !_visible; 21 | }, 22 | ), 23 | ); 24 | } 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return Scaffold( 29 | backgroundColor: Color.fromARGB(255, 10, 9, 8), 30 | body: Column( 31 | mainAxisAlignment: MainAxisAlignment.center, 32 | crossAxisAlignment: CrossAxisAlignment.center, 33 | children: [ 34 | Center( 35 | child: AnimatedOpacity( 36 | opacity: _visible ? 1.0 : 0.0, 37 | duration: Duration(milliseconds: 3000), 38 | child: Image.asset( 39 | 'assets/logo.png', 40 | ), 41 | ), 42 | ), 43 | Container( 44 | margin: EdgeInsets.all(30), 45 | child: CircularProgressIndicator( 46 | valueColor: new AlwaysStoppedAnimation( 47 | Colors.white, 48 | ), 49 | ), 50 | ) 51 | ], 52 | ), 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /word_clock/lib/util/device_scanner.dart: -------------------------------------------------------------------------------- 1 | import 'package:wifi/wifi.dart'; 2 | import 'package:ping_discover_network/ping_discover_network.dart'; 3 | import 'dart:async'; 4 | import 'package:http/http.dart' as http; 5 | import 'dart:convert'; 6 | import 'dart:io'; 7 | 8 | import '../model/clock.dart'; 9 | 10 | class DeviceScanner { 11 | static Future> scanDevicesInLocalNetwork() async { 12 | List clocks = []; 13 | final String ip = await Wifi.ip; 14 | final String subnet = ip.substring(0, ip.lastIndexOf('.')); 15 | final int port = 80; 16 | 17 | final stream = NetworkAnalyzer.discover(subnet, port); 18 | stream.listen((NetworkAddress addr) { 19 | Future clock = _testConnection(addr.ip); 20 | clock.then((clockValue) { 21 | if (!clocks.contains(ip)) { 22 | if (null != clockValue) { 23 | print( 24 | 'Found a device of type ${clockValue.clockType} with ip $ip! Adding it to list of clocks'); 25 | List containedClocks = []; 26 | for (Clock clock in clocks) { 27 | if (clock.ipAddress.compareTo(ip) == 0) { 28 | containedClocks.add(clock); 29 | } 30 | } 31 | 32 | if (containedClocks.length == 0) { 33 | clocks.add(clockValue); 34 | } 35 | } 36 | } 37 | }); 38 | }, onDone: () { 39 | print("Finished Scanning"); 40 | print("Found ${clocks.length} clocks!"); 41 | return clocks; 42 | }); 43 | 44 | return clocks; 45 | } 46 | 47 | static Future _testConnection(final String ip) async { 48 | http.Client client = http.Client(); 49 | try { 50 | if (ip.endsWith(".2") || ip.endsWith(".1")) { 51 | return null; 52 | } 53 | final response = await client.get(Uri.parse('http://192.168.2.147/')); 54 | 55 | if (response.statusCode == 200) { 56 | if (!response.body.startsWith("<")) { 57 | var data = json.decode(response.body); 58 | final String clockType = data["variables"]["type"]; 59 | final String roomName = data["variables"]["room_name"]; 60 | return Clock(clockType, ip, roomName); 61 | } 62 | } 63 | } on SocketException catch (e) { 64 | //NOP 65 | } on TimeoutException catch (e) { 66 | //NOP 67 | } 68 | client.close(); 69 | return null; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /word_clock/lib/widgets/clock_list/clock_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import './clock_list_item.dart'; 4 | import '../../model/clock.dart'; 5 | 6 | class ClockList extends StatelessWidget { 7 | final List _clocks; 8 | ClockList(this._clocks); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Flex( 13 | crossAxisAlignment: CrossAxisAlignment.start, 14 | direction: Axis.vertical, 15 | children: [ 16 | Expanded( 17 | child: ListView.builder( 18 | shrinkWrap: true, 19 | itemCount: _clocks.length, 20 | itemBuilder: (BuildContext ctxt, int index) { 21 | return ClockListItem( 22 | _clocks[index], 23 | ); 24 | }, 25 | ), 26 | ), 27 | ], 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /word_clock/lib/widgets/clock_list/clock_list_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../model/clock.dart'; 3 | import '../../screens/home_screen.dart'; 4 | 5 | class ClockListItem extends StatelessWidget { 6 | final Clock _clock; 7 | 8 | ClockListItem(this._clock); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | alignment: Alignment.center, 14 | margin: EdgeInsets.all(40), 15 | child: ListTile( 16 | title: Text( 17 | "${_clock.clockType.compareTo("word-clock") == 0 ? "Word Clock" : "Random Clock"} @ ${_clock.roomName}"), 18 | subtitle: Image.asset( 19 | "assets/word-clock.png", 20 | scale: 1.5, 21 | ), 22 | onTap: () { 23 | Navigator.push( 24 | context, 25 | MaterialPageRoute( 26 | builder: (context) => 27 | HomeScreen(_clock.ipAddress, _clock.roomName), 28 | ), 29 | ); 30 | }, 31 | ), 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /word_clock/lib/widgets/clocks/word_clock/clock_element.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | enum ElementType { 4 | MINUTE, 5 | HOUR, 6 | } 7 | 8 | class ClockElement extends StatefulWidget { 9 | final String _text; 10 | Color _color; 11 | final List _numericValues; 12 | final ElementType _elementType; 13 | _ClockElementState _state; 14 | 15 | ClockElement(this._text, this._color, 16 | [this._numericValues, this._elementType]); 17 | 18 | int getNumericValuesAtIndex(int index) { 19 | return _numericValues[index]; 20 | } 21 | 22 | ElementType getClockElementType() { 23 | return _elementType; 24 | } 25 | 26 | void setColor(final Color color) { 27 | _color = color; 28 | if (_state != null) { 29 | _state.setColor(); 30 | } 31 | } 32 | 33 | String getText() { 34 | return _text; 35 | } 36 | 37 | @override 38 | _ClockElementState createState() { 39 | _state = _ClockElementState(); 40 | return _state; 41 | } 42 | } 43 | 44 | class _ClockElementState extends State { 45 | void setColor() { 46 | setState(() {}); 47 | } 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return Container( 52 | decoration: BoxDecoration( 53 | shape: BoxShape.circle, 54 | color: widget._color, 55 | ), 56 | child: Container( 57 | alignment: Alignment.center, 58 | child: Text( 59 | widget._text, 60 | style: TextStyle( 61 | color: Colors.white, 62 | ), 63 | ), 64 | ), 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /word_clock/lib/widgets/clocks/word_clock/word_clock.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'clock_element.dart'; 3 | import 'dart:async'; 4 | import 'package:flutter/services.dart' show rootBundle; 5 | import 'dart:math'; 6 | 7 | class WordClock extends StatefulWidget { 8 | List _clockLetters = []; 9 | Color _currentColor = const Color.fromARGB(255, 0, 0, 255); 10 | bool _animate; 11 | 12 | WordClock(this._clockLetters, this._currentColor, this._animate); 13 | 14 | @override 15 | _WordClockState createState() => _WordClockState(); 16 | } 17 | 18 | class _WordClockState extends State { 19 | List _clockElements; 20 | Map> _wordDefintions; 21 | 22 | Future>> _loadClockLetterIndices() { 23 | Map> retVal = Map(); 24 | return rootBundle 25 | .loadString('assets/clock_element_indices.txt') 26 | .then((String contents) { 27 | List wordDefinitions = contents.split("\n"); 28 | for (String wordDefinition in wordDefinitions) { 29 | List index = wordDefinition.split(":"); 30 | int wordIndex = int.parse(index[0]); 31 | int wordIndexFrom = int.parse(index[1].split(",")[0]); 32 | int wordIndexTo = int.parse(index[1].split(",")[1]); 33 | 34 | retVal[wordIndex] = MapEntry(wordIndexFrom, wordIndexTo); 35 | } 36 | 37 | return retVal; 38 | }); 39 | } 40 | 41 | @override 42 | void initState() { 43 | super.initState(); 44 | _setup(); 45 | } 46 | 47 | void _showTime(final TimeOfDay currentTime) { 48 | print(currentTime); 49 | 50 | for (int i = 0; i < _clockElements.length; i++) { 51 | _clockElements[i].setColor(Colors.black); 52 | } 53 | 54 | int hour = 55 | currentTime.hour <= 12 ? currentTime.hour : currentTime.hour - 12; 56 | 57 | int minute = currentTime.minute; 58 | 59 | MapEntry entr = _findClockElement(minute, true); 60 | 61 | for (MapEntry> entry in _wordDefintions.entries) { 62 | if (entry.key == -1 || entry.key == -2) { 63 | for (int i = entry.value.key; i <= entry.value.value; i++) { 64 | _clockElements[i].setColor(Colors.red); 65 | } 66 | } 67 | 68 | if (minute == 0 && entry.key == -6) { 69 | for (int i = entry.value.key; i <= entry.value.value; i++) { 70 | _clockElements[i].setColor(Colors.red); 71 | } 72 | } 73 | 74 | if (minute == 30 && entry.key == -5) { 75 | for (int i = entry.value.key; i <= entry.value.value; i++) { 76 | _clockElements[i].setColor(Colors.red); 77 | } 78 | hour++; 79 | } 80 | } 81 | 82 | if (entr != null) { 83 | for (int i = entr.key; i <= entr.value; i++) { 84 | _clockElements[i].setColor(Colors.red); 85 | } 86 | } 87 | 88 | if (60 - minute > 35 && 89 | minute != 0 && 90 | minute != 35 && 91 | minute != 25 && 92 | minute != 30) { 93 | for (int i = _wordDefintions[-4].key; 94 | i <= _wordDefintions[-4].value; 95 | i++) { 96 | _clockElements[i].setColor(Colors.red); 97 | } 98 | } else if (minute != 0 && minute != 35 && minute != 25 && minute != 30) { 99 | for (int i = _wordDefintions[-3].key; 100 | i <= _wordDefintions[-3].value; 101 | i++) { 102 | _clockElements[i].setColor(Colors.red); 103 | } 104 | hour++; 105 | } 106 | 107 | if (minute == 25) { 108 | for (int i = _wordDefintions[-3].key; 109 | i <= _wordDefintions[-3].value; 110 | i++) { 111 | _clockElements[i].setColor(Colors.red); 112 | } 113 | for (int i = _wordDefintions[-5].key; 114 | i <= _wordDefintions[-5].value; 115 | i++) { 116 | _clockElements[i].setColor(Colors.red); 117 | } 118 | hour++; 119 | } else if (minute == 35) { 120 | for (int i = _wordDefintions[-4].key; 121 | i <= _wordDefintions[-4].value; 122 | i++) { 123 | _clockElements[i].setColor(Colors.red); 124 | } 125 | for (int i = _wordDefintions[-5].key; 126 | i <= _wordDefintions[-5].value; 127 | i++) { 128 | _clockElements[i].setColor(Colors.red); 129 | } 130 | hour++; 131 | } 132 | 133 | entr = _findClockElement(hour, false); 134 | for (int i = entr.key; i <= entr.value; i++) { 135 | _clockElements[i].setColor(Colors.red); 136 | } 137 | } 138 | 139 | MapEntry _findClockElement(int value, final bool isMinute) { 140 | int startIndex = 0; 141 | if (!isMinute) { 142 | startIndex = 9; 143 | if (value > 12) { 144 | value = value - 12; 145 | } 146 | } 147 | 148 | if (isMinute) { 149 | value = value - (value % 5); 150 | } 151 | 152 | if (isMinute) { 153 | switch (value) { 154 | case 5: 155 | case 55: 156 | value = -10; 157 | break; 158 | case 10: 159 | case 50: 160 | value = -11; 161 | break; 162 | case 15: 163 | case 45: 164 | value = -12; 165 | break; 166 | case 20: 167 | case 40: 168 | value = -13; 169 | break; 170 | case 25: 171 | case 35: 172 | value = -10; 173 | break; 174 | default: 175 | } 176 | } 177 | 178 | for (int i = startIndex; i < _wordDefintions.entries.length; i++) { 179 | if (_wordDefintions.entries.toList()[i].key == value) { 180 | return _wordDefintions.entries.toList()[i].value; 181 | } 182 | } 183 | return null; 184 | } 185 | 186 | void _checkTime() { 187 | Timer( 188 | Duration(seconds: 1), 189 | () { 190 | _showTime( 191 | TimeOfDay( 192 | hour: DateTime.now().hour, 193 | minute: DateTime.now().minute, 194 | ), 195 | ); 196 | _checkTime(); 197 | }, 198 | ); 199 | } 200 | 201 | void _setup() { 202 | _clockElements = widget._clockLetters 203 | .map( 204 | (title) => ClockElement( 205 | title, 206 | widget._currentColor, 207 | ), 208 | ) 209 | .toList(); 210 | if (widget._animate) { 211 | _loadClockLetterIndices().then((value) { 212 | _wordDefintions = value; 213 | _checkTime(); 214 | }); 215 | } 216 | } 217 | 218 | @override 219 | Widget build(BuildContext context) { 220 | return Padding( 221 | padding: EdgeInsets.all(50), 222 | child: GridView.count( 223 | physics: const NeverScrollableScrollPhysics(), 224 | crossAxisCount: 11, 225 | children: _clockElements, 226 | ), 227 | ); 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /word_clock/lib/widgets/configuration_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ConfigurationItem extends StatelessWidget { 4 | final String _title; 5 | final String _initialValue; 6 | final EdgeInsets _edgeInsets; 7 | final Function _onTextChanged; 8 | 9 | ///_title: The title of the configuration item 10 | ///_edgeInsets: The amount of padding to be used. The default is EdgeInsets.only(top: 10, bottom: 10) 11 | ///_onTextChanged: Function to be called when the input field is changed 12 | ConfigurationItem(this._title, this._onTextChanged, 13 | [this._edgeInsets, this._initialValue]); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return Padding( 18 | padding: _edgeInsets, 19 | child: TextField( 20 | decoration: InputDecoration( 21 | hintText: _title, 22 | ), 23 | onChanged: (wifiPassword) { 24 | _onTextChanged(wifiPassword); 25 | }, 26 | controller: TextEditingController()..text = _initialValue, 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /word_clock/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: word_clock 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # Read more about versioning at semver.org. 10 | version: 1.0.0+1 11 | 12 | environment: 13 | sdk: ">=2.0.0-dev.68.0 <3.0.0" 14 | 15 | dependencies: 16 | flutter: 17 | sdk: flutter 18 | flutter_colorpicker: ^0.3.4 19 | flushbar: ^1.3.0 20 | ping_discover_network: ^0.1.2 21 | wifi: ^0.1.5 22 | http: ^0.12.0+2 23 | 24 | # The following adds the Cupertino Icons font to your application. 25 | # Use with the CupertinoIcons class for iOS style icons. 26 | cupertino_icons: ^0.1.2 27 | 28 | dev_dependencies: 29 | flutter_launcher_icons: "^0.7.0" 30 | flutter_test: 31 | sdk: flutter 32 | 33 | flutter_icons: 34 | android: "launcher_icon" 35 | ios: true 36 | image_path: "assets/icon.png" 37 | 38 | # For information on the generic Dart part of this file, see the 39 | # following page: https://www.dartlang.org/tools/pub/pubspec 40 | 41 | # The following section is specific to Flutter. 42 | flutter: 43 | 44 | # The following line ensures that the Material Icons font is 45 | # included with your application, so that you can use the icons in 46 | # the material Icons class. 47 | uses-material-design: true 48 | 49 | # To add assets to your application, add an assets section, like this: 50 | assets: 51 | - assets/logo.png 52 | - assets/clock_text.txt 53 | - assets/clock_element_indices.txt 54 | - assets/word-clock.png 55 | 56 | # An image asset can refer to one or more resolution-specific "variants", see 57 | # https://flutter.io/assets-and-images/#resolution-aware. 58 | 59 | # For details regarding adding assets from package dependencies, see 60 | # https://flutter.io/assets-and-images/#from-packages 61 | 62 | # To add custom fonts to your application, add a fonts section here, 63 | # in this "flutter" section. Each entry in this list should have a 64 | # "family" key with the font family name, and a "fonts" key with a 65 | # list giving the asset and other descriptors for the font. For 66 | # example: 67 | # fonts: 68 | # - family: Schyler 69 | # fonts: 70 | # - asset: fonts/Schyler-Regular.ttf 71 | # - asset: fonts/Schyler-Italic.ttf 72 | # style: italic 73 | # - family: Trajan Pro 74 | # fonts: 75 | # - asset: fonts/TrajanPro.ttf 76 | # - asset: fonts/TrajanPro_Bold.ttf 77 | # weight: 700 78 | # 79 | # For details regarding fonts from package dependencies, 80 | # see https://flutter.io/custom-fonts/#from-packages 81 | -------------------------------------------------------------------------------- /word_clock/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:word_clock/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | --------------------------------------------------------------------------------