├── settings.bin ├── .gitignore ├── label.txt ├── README.md ├── calend.h ├── LICENSE └── calend.c /settings.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bak 2 | *.elf 3 | *.map 4 | *.o 5 | foo -------------------------------------------------------------------------------- /label.txt: -------------------------------------------------------------------------------- 1 | Calendar 2 | RU Календарь 3 | IT Calendario 4 | ES Calendario 5 | FR Calendrier 6 | DE Kalender -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Calend 2 | Calendar application for BipOS 3 | 4 | #Intro 5 | From version MNVolkov BipOS 0.5 the startup code of the applications is completely redisigned. Each application now is a separate file stored in resources. The executable file format is Arm-elf (or simply"elf"). The mod got a new name BipOS. When the MOD starts, resources are scanned for applications. Each firmware has a different amount of resources, and applications are always placed at the end. Therefore, the loader looks for resources by Elf signature starting with resource 930. Found applications are placed in the menu "Applications". 6 | 7 | The algorithm for calculating the day of the week works for any date in the Gregorian calendar. The range of the calendar from 1600 to 3000 years.At startup, the current month is displayed, the current day is highlighted in color. There is ability to select another period through turning: swipe left-right to switch the months, swipe up and down - switch the years. 8 | 9 | More information at https://myamazfit.ru/threads/bip-application-develop-for-bipos-sdk-en.1171/ 10 | -------------------------------------------------------------------------------- /calend.h: -------------------------------------------------------------------------------- 1 | /* 2 | (С) Волков Максим 2019 ( mr-volkov+bip@yandex.ru ) 3 | Календарь для Amazfit Bip 4 | 5 | */ 6 | #ifndef __CALEND_H__ 7 | #define __CALEND_H__ 8 | 9 | // Значения цветовой схемы 10 | #define CALEND_COLOR_BG 0 // фон календаря 11 | #define CALEND_COLOR_MONTH 1 // цвет названия текущего месяца 12 | #define CALEND_COLOR_YEAR 2 // цвет текущего года 13 | #define CALEND_COLOR_WORK_NAME 3 // цвет названий дней будни 14 | #define CALEND_COLOR_HOLY_NAME_BG 4 // фон названий дней выходные 15 | #define CALEND_COLOR_HOLY_NAME_FG 5 // цвет названий дней выходные 16 | #define CALEND_COLOR_SEPAR 6 // цвет разделителей календаря 17 | #define CALEND_COLOR_NOT_CUR_WORK 7 // цвет чисел НЕ текущего месяца будни 18 | #define CALEND_COLOR_NOT_CUR_HOLY_BG 8 // фон чисел НЕ текущего месяца выходные 19 | #define CALEND_COLOR_NOT_CUR_HOLY_FG 9 // цвет чисел НЕ текущего месяца выходные 20 | #define CALEND_COLOR_CUR_WORK 10 // цвет чисел текущего месяца будни 21 | #define CALEND_COLOR_CUR_HOLY_BG 11 // фон чисел текущего месяца выходные 22 | #define CALEND_COLOR_CUR_HOLY_FG 12 // цвет чисел текущего месяца выходные 23 | #define CALEND_COLOR_TODAY_BG 13 // цвет чисел текущего дня 24 | #define CALEND_COLOR_TODAY_FG 14 // фон чисел текущего дня 25 | 26 | // количество цыетовых схем 27 | #define COLOR_SCHEME_COUNT 5 28 | 29 | // смещение адреса для хранения настроек календаря 30 | #define OPT_OFFSET_CALEND_OPT 0 31 | 32 | #if FW_VERSION==latin_1_1_5_12 || FW_VERSION==latin_1_1_5_36 33 | // параметры рисования цифр календаря 34 | // строка: от 7 до 169 = 162рх в ширину 7 чисел по 24рх на число 7+(24)*6+22+3 35 | // строки: от 57 до 174 = 117рх в высоту 6 строк по 22рх на строку 1+(22)*5+22 36 | 37 | #define CALEND_Y_BASE 30 // базовая высота начала отрисовки календаря 38 | //#define CALEND_NAME_HEIGHT 19 // высота строки названий дней недели 39 | //#define CALEND_DAYS_Y_BASE CALEND_Y_BASE+1+V_MARGIN+CALEND_NAME_HEIGHT+V_MARGIN+1 // высота базы чисел месяца 40 | #define WIDTH 24 // ширина цифр числа 41 | #define HEIGHT 19 // высота цифр числа 42 | #define V_SPACE 0 // вертикальный отступ между строками чисел 43 | #define H_SPACE 0 // горизонтальный отступ между колонками чисел 44 | #define H_MARGIN 4 // горизонтальный отступ от края экрана 45 | #define V_MARGIN 1 // вертикальный отступ от заголовка (базы) 46 | 47 | #elif FW_VERSION==not_latin_1_1_2_05 48 | // параметры рисования цифр календаря 49 | // строка: от 7 до 169 = 162рх в ширину 7 чисел по 24рх на число 7+(24)*6+24+3 50 | // строки: от 57 до 174 = 117рх в высоту 6 строк по 22рх на строку 1+(22)*5+20 51 | 52 | #define CALEND_Y_BASE 25 // базовая высота начала отрисовки календаря 53 | //#define CALEND_NAME_HEIGHT FONT_HEIGHT+2 // высота строки названий дней недели 54 | //#define CALEND_DAYS_Y_BASE CALEND_Y_BASE+1+V_MARGIN+CALEND_NAME_HEIGHT+V_MARGIN+1 // высота базы чисел месяца 56 55 | #define WIDTH 24 // ширина цифр числа 56 | #define HEIGHT 20 // высота цифр числа 57 | #define V_SPACE 0 // вертикальный отступ между строками чисел 58 | #define H_SPACE 0 // горизонтальный отступ между колонками чисел 59 | #define H_MARGIN 4 // горизонтальный отступ от края экрана 60 | #define V_MARGIN 1 // вертикальный отступ от заголовка (базы) 61 | #endif 62 | 63 | 64 | #define INACTIVITY_PERIOD 30000 // время по прошествии которого выходим 65 | 66 | // сохраняемые опции календаря 67 | struct calend_opt_ { 68 | unsigned char color_scheme; // цветовая схема 69 | }; 70 | 71 | // текущие данные просматриваемого/редактируемого календаря 72 | struct calend_ { 73 | Elf_proc_* proc; // указатель на данные запущенного процесса 74 | void* ret_f; // адрес функции возврата 75 | unsigned char color_scheme; // цветовая схема 76 | // отображаемый месяц 77 | unsigned int day; // день 78 | unsigned int month; // месяц 79 | unsigned int year; // год 80 | }; 81 | 82 | 83 | void show_calend_screen (void *return_screen); 84 | void key_press_calend_screen(); 85 | int dispatch_calend_screen (void *param); 86 | void calend_screen_job(); 87 | 88 | void draw_month(unsigned int day, unsigned int month, unsigned int year); 89 | unsigned char wday(unsigned int day,unsigned int month,unsigned int year); 90 | unsigned char isLeapYear(unsigned int year); 91 | 92 | #endif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /calend.c: -------------------------------------------------------------------------------- 1 | /* 2 | (С) Волков Максим 2019 ( Maxim.N.Volkov@ya.ru ) 3 | 4 | Календарь v1.0 5 | Приложение простого календаря. 6 | Алгоритм вычисления дня недели работает для любой даты григорианского календаря позднее 1583 года. 7 | Григорианский календарь начал действовать в 1582 — после 4 октября сразу настало 15 октября. 8 | 9 | Календарь от 1600 до 3000 года 10 | Функции перелистывания каленаря вверх-вниз - месяц, стрелками год 11 | При нажатии на название месяца устанавливается текущая дата 12 | 13 | 14 | v.1.1 15 | - исправлены переходы в при запуске из бстрого меню 16 | 17 | */ 18 | 19 | #include 20 | #include "calend.h" 21 | #define DEBUG_LOG 22 | 23 | // структура меню экрана календаря 24 | struct regmenu_ menu_calend_screen = { 25 | 55, 26 | 1, 27 | 0, 28 | dispatch_calend_screen, 29 | key_press_calend_screen, 30 | calend_screen_job, 31 | 0, 32 | show_calend_screen, 33 | 0, 34 | 0 35 | }; 36 | 37 | int main(int param0, char** argv){ // переменная argv не определена 38 | show_calend_screen((void*) param0); 39 | } 40 | 41 | void show_calend_screen (void *param0){ 42 | struct calend_** calend_p = get_ptr_temp_buf_2(); // указатель на указатель на данные экрана 43 | struct calend_ * calend; // указатель на данные экрана 44 | struct calend_opt_ calend_opt; // опции календаря 45 | 46 | #ifdef DEBUG_LOG 47 | log_printf(5, "[show_calend_screen] param0=%X; *temp_buf_2=%X; menu_overlay=%d", (int)param0, (int*)get_ptr_temp_buf_2(), get_var_menu_overlay()); 48 | log_printf(5, " #calend_p=%X; *calend_p=%X", (int)calend_p, (int)*calend_p); 49 | #endif 50 | 51 | if ( (param0 == *calend_p) && get_var_menu_overlay()){ // возврат из оверлейного экрана (входящий звонок, уведомление, будильник, цель и т.д.) 52 | 53 | #ifdef DEBUG_LOG 54 | log_printf(5, " #from overlay"); 55 | log_printf(5, "\r\n"); 56 | #endif 57 | 58 | calend = *calend_p; // указатель на данные необходимо сохранить для исключения 59 | // высвобождения памяти функцией reg_menu 60 | *calend_p = NULL; // обнуляем указатель для передачи в функцию reg_menu 61 | 62 | // создаем новый экран, при этом указатели temp_buf_1 и temp_buf_2 были равны 0 и память не была высвобождена 63 | reg_menu(&menu_calend_screen, 0); // menu_overlay=0 64 | 65 | *calend_p = calend; // восстанавливаем указатель на данные после функции reg_menu 66 | 67 | draw_month(0, calend->month, calend->year); 68 | 69 | } else { // если запуск функции произошел из меню, 70 | 71 | #ifdef DEBUG_LOG 72 | log_printf(5, " #from menu"); 73 | log_printf(5, "\r\n"); 74 | #endif 75 | // создаем экран 76 | reg_menu(&menu_calend_screen, 0); 77 | 78 | // выделяем необходимую память и размещаем в ней данные 79 | *calend_p = (struct calend_ *)pvPortMalloc(sizeof(struct calend_)); 80 | calend = *calend_p; // указатель на данные 81 | 82 | // очистим память под данные 83 | _memclr(calend, sizeof(struct calend_)); 84 | 85 | calend->proc = param0; 86 | 87 | // запомним адрес указателя на функцию в которую необходимо вернуться после завершения данного экрана 88 | if ( param0 && calend->proc->elf_finish ) // если указатель на возврат передан, то возвоащаемся на него 89 | calend->ret_f = calend->proc->elf_finish; 90 | else // если нет, то на циферблат 91 | calend->ret_f = show_watchface; 92 | 93 | struct datetime_ datetime; 94 | _memclr(&datetime, sizeof(struct datetime_)); 95 | 96 | // получим текущую дату 97 | get_current_date_time(&datetime); 98 | 99 | calend->day = datetime.day; 100 | calend->month = datetime.month; 101 | calend->year = datetime.year; 102 | 103 | // считаем опции из flash памяти, если значение в флэш-памяти некорректное то берем первую схему 104 | // текущая цветовая схема хранится о смещению 0 105 | ElfReadSettings(calend->proc->index_listed, &calend_opt, OPT_OFFSET_CALEND_OPT, sizeof(struct calend_opt_)); 106 | 107 | if (calend_opt.color_scheme < COLOR_SCHEME_COUNT) 108 | calend->color_scheme = calend_opt.color_scheme; 109 | else 110 | calend->color_scheme = 0; 111 | 112 | draw_month(calend->day, calend->month, calend->year); 113 | } 114 | 115 | // при бездействии погасить подсветку и не выходить 116 | set_display_state_value(8, 1); 117 | set_display_state_value(2, 1); 118 | 119 | // таймер на job на 20с где выход. 120 | set_update_period(1, INACTIVITY_PERIOD); 121 | 122 | } 123 | 124 | void draw_month(unsigned int day, unsigned int month, unsigned int year){ 125 | struct calend_** calend_p = get_ptr_temp_buf_2(); // указатель на указатель на данные экрана 126 | struct calend_ * calend = *calend_p; // указатель на данные экрана 127 | 128 | 129 | /* 130 | 0: CALEND_COLOR_BG фон календаря 131 | 1: CALEND_COLOR_MONTH цвет названия текущего месяца 132 | 2: CALEND_COLOR_YEAR цвет текущего года 133 | 3: CALEND_COLOR_WORK_NAME цвет названий дней будни 134 | 4: CALEND_COLOR_HOLY_NAME_BG фон названий дней выходные 135 | 5: CALEND_COLOR_HOLY_NAME_FG цвет названий дней выходные 136 | 6: CALEND_COLOR_SEPAR цвет разделителей календаря 137 | 7: CALEND_COLOR_NOT_CUR_WORK цвет чисел НЕ текущего месяца будни 138 | 8: CALEND_COLOR_NOT_CUR_HOLY_BG фон чисел НЕ текущего месяца выходные 139 | 9: CALEND_COLOR_NOT_CUR_HOLY_FG цвет чисел НЕ текущего месяца выходные 140 | 10: CALEND_COLOR_CUR_WORK цвет чисел текущего месяца будни 141 | 11: CALEND_COLOR_CUR_HOLY_BG фон чисел текущего месяца выходные 142 | 12: CALEND_COLOR_CUR_HOLY_FG цвет чисел текущего месяца выходные 143 | 13: CALEND_COLOR_TODAY_BG фон чисел текущего дня; bit 31 - заливка: =0 заливка цветом фона, =1 только рамка, фон как у числа не текущего месяца 144 | 14: CALEND_COLOR_TODAY_FG цвет чисел текущего дня 145 | */ 146 | 147 | 148 | static unsigned char short_color_scheme[COLOR_SCHEME_COUNT][15] = 149 | /* черная тема без выделения выходных*/ {// 0 1 2 3 4 5 6 150 | {COLOR_SH_BLACK, COLOR_SH_YELLOW, COLOR_SH_AQUA, COLOR_SH_WHITE, COLOR_SH_RED, COLOR_SH_WHITE, COLOR_SH_WHITE, 151 | COLOR_SH_GREEN, COLOR_SH_BLACK, COLOR_SH_AQUA, COLOR_SH_YELLOW, COLOR_SH_BLACK, COLOR_SH_WHITE, COLOR_SH_YELLOW, COLOR_SH_BLACK}, 152 | // 7 8 9 10 11 12 13 14 153 | // 0 1 2 3 4 5 6 154 | /* белая тема без выделения выходных*/ {COLOR_SH_WHITE, COLOR_SH_BLACK, COLOR_SH_BLUE, COLOR_SH_BLACK, COLOR_SH_RED, COLOR_SH_WHITE, COLOR_SH_BLACK, 155 | COLOR_SH_BLUE, COLOR_SH_WHITE, COLOR_SH_AQUA, COLOR_SH_BLACK, COLOR_SH_WHITE, COLOR_SH_RED, COLOR_SH_BLUE, COLOR_SH_WHITE}, 156 | // 7 8 9 10 11 12 13 14 157 | // 0 1 2 3 4 5 6 158 | /* черная тема с выделением выходных*/ {COLOR_SH_BLACK, COLOR_SH_YELLOW, COLOR_SH_AQUA, COLOR_SH_WHITE, COLOR_SH_RED, COLOR_SH_WHITE, COLOR_SH_WHITE, 159 | COLOR_SH_GREEN, COLOR_SH_RED, COLOR_SH_AQUA, COLOR_SH_YELLOW, COLOR_SH_RED, COLOR_SH_WHITE, COLOR_SH_AQUA, COLOR_SH_BLACK}, 160 | // 7 8 9 10 11 12 13 14 161 | // 0 1 2 3 4 5 6 162 | /* белая тема с выделением выходных*/ {COLOR_SH_WHITE, COLOR_SH_BLACK, COLOR_SH_BLUE, COLOR_SH_BLACK, COLOR_SH_RED, COLOR_SH_WHITE, COLOR_SH_BLACK, 163 | COLOR_SH_BLUE, COLOR_SH_RED, COLOR_SH_BLUE, COLOR_SH_BLACK, COLOR_SH_RED, COLOR_SH_BLACK, COLOR_SH_BLUE, COLOR_SH_WHITE}, 164 | // 7 8 9 10 11 12 13 14 165 | // 0 1 2 3 4 5 6 166 | /* черная тема без выделения выходных*/ {COLOR_SH_BLACK, COLOR_SH_YELLOW, COLOR_SH_AQUA, COLOR_SH_WHITE, COLOR_SH_RED, COLOR_SH_WHITE, COLOR_SH_WHITE, 167 | /*с рамкой выделения сегодняшнего дня*/ COLOR_SH_GREEN, COLOR_SH_BLACK, COLOR_SH_AQUA, COLOR_SH_YELLOW, COLOR_SH_BLACK, COLOR_SH_WHITE, COLOR_SH_AQUA|(1<<7), COLOR_SH_BLACK}, 168 | // 7 8 9 10 11 12 13 14 169 | 170 | }; 171 | 172 | int color_scheme[COLOR_SCHEME_COUNT][15]; 173 | 174 | 175 | for (unsigned char i=0;icolor_scheme][CALEND_COLOR_BG]); // фон календаря 268 | fill_screen_bg(); 269 | 270 | set_graph_callback_to_ram_1(); 271 | load_font(); // подгружаем шрифты 272 | 273 | _sprintf(&text_buffer[0], " %d", year); 274 | int month_text_width = text_width(monthname[month]); 275 | int year_text_width = text_width(&text_buffer[0]); 276 | 277 | set_fg_color(color_scheme[calend->color_scheme][CALEND_COLOR_MONTH]); // цвет месяца 278 | text_out(monthname[month], (176-month_text_width-year_text_width)/2 ,5); // вывод названия месяца 279 | 280 | set_fg_color(color_scheme[calend->color_scheme][CALEND_COLOR_YEAR]); // цвет года 281 | text_out(&text_buffer[0], (176+month_text_width-year_text_width)/2 ,5); // вывод года 282 | 283 | text_out("←", 5 ,5); // вывод стрелки влево 284 | text_out("→", 176-5-text_width("→"),5); // вывод стрелки вправо 285 | 286 | int calend_name_height = get_text_height(); 287 | 288 | set_fg_color(color_scheme[calend->color_scheme][CALEND_COLOR_SEPAR]); 289 | draw_horizontal_line(CALEND_Y_BASE, H_MARGIN, 176-H_MARGIN); // Верхний разделитель названий дней недели 290 | draw_horizontal_line(CALEND_Y_BASE+1+V_MARGIN+calend_name_height+1+V_MARGIN, H_MARGIN, 176-H_MARGIN); // Нижний разделитель названий дней недели 291 | //draw_horizontal_line(175, H_MARGIN, 176-H_MARGIN); // Нижний разделитель месяца 292 | 293 | // Названия дней недели 294 | for (unsigned i=1; (i<=7);i++){ 295 | if ( i>5 ){ // выходные 296 | set_bg_color(color_scheme[calend->color_scheme][CALEND_COLOR_HOLY_NAME_BG]); 297 | set_fg_color(color_scheme[calend->color_scheme][CALEND_COLOR_HOLY_NAME_FG]); 298 | } else { // рабочие 299 | set_bg_color(color_scheme[calend->color_scheme][CALEND_COLOR_BG]); 300 | set_fg_color(color_scheme[calend->color_scheme][CALEND_COLOR_WORK_NAME]); 301 | } 302 | 303 | 304 | // отрисовка фона названий выходных 305 | int pos_x1 = H_MARGIN +(i-1)*(WIDTH + H_SPACE); 306 | int pos_y1 = CALEND_Y_BASE+V_MARGIN+1; 307 | int pos_x2 = pos_x1 + WIDTH; 308 | int pos_y2 = pos_y1 + calend_name_height; 309 | 310 | // фон для каждого названия дня недели 311 | draw_filled_rect_bg(pos_x1, pos_y1, pos_x2, pos_y2); 312 | 313 | // вывод названий дней недели. если ширина названия больше чем ширина поля, выводим короткие названия 314 | if (text_width(weekday_string[1]) <= (WIDTH - 2)) 315 | text_out_center(weekday_string[i], pos_x1 + WIDTH/2, pos_y1 + (calend_name_height-get_text_height())/2 ); 316 | else 317 | text_out_center(weekday_string_short[i], pos_x1 + WIDTH/2, pos_y1 + (calend_name_height-get_text_height())/2 ); 318 | } 319 | 320 | 321 | int calend_days_y_base = CALEND_Y_BASE+1+V_MARGIN+calend_name_height+V_MARGIN+1; 322 | 323 | if (isLeapYear(year)>0) day_month[2]=29; 324 | 325 | unsigned char d=wday(1,month, year); 326 | unsigned char m=month; 327 | if (d>1) { 328 | m=(month==1)?12:month-1; 329 | d=day_month[m]-d+2; 330 | } 331 | 332 | // числа месяца 333 | for (unsigned i=1; (i<=7*6);i++){ 334 | 335 | unsigned char row = (i-1)/7; 336 | unsigned char col = (i-1)%7+1; 337 | 338 | _sprintf (&text_buffer[0], "%2.0d", d); 339 | 340 | int bg_color = 0; 341 | int fg_color = 0; 342 | int frame_color = 0; // цветрамки 343 | int frame = 0; // 1-рамка; 0 - заливка 344 | 345 | // если текущий день текущего месяца 346 | if ( (m==month)&&(d==day) ){ 347 | 348 | if ( color_scheme[calend->color_scheme][CALEND_COLOR_TODAY_BG] & (1<<31) ) {// если заливка отключена только рамка 349 | 350 | // цвет рамки устанавливаем CALEND_COLOR_TODAY_BG, фон внутри рамки и цвет текста такой же как был 351 | frame_color = (color_scheme[calend->color_scheme][CALEND_COLOR_TODAY_BG &COLOR_MASK]); 352 | // рисуем рамку 353 | frame = 1; 354 | 355 | if ( col > 5 ){ // если выходные 356 | bg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_CUR_HOLY_BG]); 357 | fg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_CUR_HOLY_FG]); 358 | } else { // если будни 359 | bg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_BG]); 360 | fg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_CUR_WORK]); 361 | }; 362 | 363 | } else { // если включена заливка 364 | if ( col > 5 ){ // если выходные 365 | bg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_TODAY_BG] & COLOR_MASK); 366 | fg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_TODAY_FG]); 367 | } else { // если будни 368 | bg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_TODAY_BG] &COLOR_MASK); 369 | fg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_TODAY_FG]); 370 | }; 371 | }; 372 | 373 | 374 | } else { 375 | if ( col > 5 ){ // если выходные 376 | if (month == m){ 377 | bg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_CUR_HOLY_BG]); 378 | fg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_CUR_HOLY_FG]); 379 | } else { 380 | bg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_NOT_CUR_HOLY_BG]); 381 | fg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_NOT_CUR_HOLY_FG]); 382 | } 383 | } else { // если будни 384 | if (month == m){ 385 | bg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_BG]); 386 | fg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_CUR_WORK]); 387 | } else { 388 | bg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_BG]); 389 | fg_color = (color_scheme[calend->color_scheme][CALEND_COLOR_NOT_CUR_WORK]); 390 | } 391 | } 392 | } 393 | 394 | 395 | 396 | // строка: от 7 до 169 = 162рх в ширину 7 чисел по 24рх на число 7+(22+2)*6+22+3 397 | // строки: от 57 до 174 = 117рх в высоту 6 строк по 19рх на строку 1+(17+2)*5+18 398 | 399 | // отрисовка фона числа 400 | int pos_x1 = H_MARGIN +(col-1)*(WIDTH + H_SPACE); 401 | int pos_y1 = calend_days_y_base + V_MARGIN + row *(HEIGHT + V_SPACE)+1; 402 | int pos_x2 = pos_x1 + WIDTH; 403 | int pos_y2 = pos_y1 + HEIGHT; 404 | 405 | if (frame){ 406 | // выводим число 407 | set_bg_color(bg_color); 408 | set_fg_color(fg_color); 409 | text_out_center(&text_buffer[0], pos_x1+WIDTH/2, pos_y1+(HEIGHT-get_text_height())/2); 410 | 411 | // рисуем рамку 412 | set_fg_color(frame_color); 413 | draw_rect(pos_x1, pos_y1, pos_x2-1, pos_y2-1); 414 | } else { 415 | // рисуем заливку 416 | set_bg_color(bg_color); 417 | draw_filled_rect_bg(pos_x1, pos_y1, pos_x2, pos_y2); 418 | 419 | // выводим число 420 | set_fg_color(fg_color); 421 | text_out_center(&text_buffer[0], pos_x1+WIDTH/2, pos_y1+(HEIGHT-get_text_height())/2); 422 | }; 423 | 424 | 425 | 426 | 427 | if ( d < day_month[m] ) { 428 | d++; 429 | } else { 430 | d=1; 431 | m=(m==12)?1:(m+1); 432 | } 433 | } 434 | 435 | 436 | 437 | }; 438 | 439 | unsigned char wday(unsigned int day,unsigned int month,unsigned int year) 440 | { 441 | signed int a = (14 - month) / 12; 442 | signed int y = year - a; 443 | signed int m = month + 12 * a - 2; 444 | return 1+(((day + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12) % 7) +6)%7; 445 | } 446 | 447 | unsigned char isLeapYear(unsigned int year){ 448 | unsigned char result = 0; 449 | if ( (year % 4) == 0 ) result++; 450 | if ( (year % 100) == 0 ) result--; 451 | if ( (year % 400) == 0 ) result++; 452 | return result; 453 | } 454 | 455 | void key_press_calend_screen(){ 456 | struct calend_** calend_p = get_ptr_temp_buf_2(); // указатель на указатель на данные экрана 457 | struct calend_ * calend = *calend_p; // указатель на данные экрана 458 | 459 | show_menu_animate(calend->ret_f, (unsigned int)show_calend_screen, ANIMATE_RIGHT); 460 | }; 461 | 462 | 463 | void calend_screen_job(){ 464 | struct calend_** calend_p = get_ptr_temp_buf_2(); // указатель на указатель на данные экрана 465 | struct calend_ * calend = *calend_p; // указатель на данные экрана 466 | 467 | // при достижении таймера обновления выходим 468 | show_menu_animate(calend->ret_f, (unsigned int)show_calend_screen, ANIMATE_LEFT); 469 | } 470 | 471 | int dispatch_calend_screen (void *param){ 472 | struct calend_** calend_p = get_ptr_temp_buf_2(); // указатель на указатель на данные экрана 473 | struct calend_ * calend = *calend_p; // указатель на данные экрана 474 | 475 | struct calend_opt_ calend_opt; // опции календаря 476 | 477 | struct datetime_ datetime; 478 | // получим текущую дату 479 | 480 | 481 | get_current_date_time(&datetime); 482 | unsigned int day; 483 | 484 | // char text_buffer[32]; 485 | struct gesture_ *gest = param; 486 | int result = 0; 487 | 488 | switch (gest->gesture){ 489 | case GESTURE_CLICK: { 490 | 491 | // вибрация при любом нажатии на экран 492 | vibrate (1, 40, 0); 493 | 494 | 495 | if ( gest->touch_pos_y < CALEND_Y_BASE ){ // кликнули по верхней строке 496 | if (gest->touch_pos_x < 44){ 497 | if ( calend->year > 1600 ) calend->year--; 498 | } else 499 | if (gest->touch_pos_x > (176-44)){ 500 | if ( calend->year < 3000 ) calend->year++; 501 | } else { 502 | calend->day = datetime.day; 503 | calend->month = datetime.month; 504 | calend->year = datetime.year; 505 | } 506 | 507 | if ( (calend->year == datetime.year) && (calend->month == datetime.month) ){ 508 | day = datetime.day; 509 | } else { 510 | day = 0; 511 | } 512 | draw_month(day, calend->month, calend->year); 513 | repaint_screen_lines(1, 176); 514 | 515 | } else { // кликнули в календарь 516 | 517 | calend->color_scheme = ((calend->color_scheme+1)%COLOR_SCHEME_COUNT); 518 | 519 | // сначала обновим экран 520 | if ( (calend->year == datetime.year) && (calend->month == datetime.month) ){ 521 | day = datetime.day; 522 | } else { 523 | day = 0; 524 | } 525 | draw_month(day, calend->month, calend->year); 526 | repaint_screen_lines(1, 176); 527 | 528 | // потом запись опций во flash память, т.к. это долгая операция 529 | // TODO: 1. если опций будет больше чем цветовая схема - переделать сохранение, чтобы сохранять перед выходом. 530 | calend_opt.color_scheme = calend->color_scheme; 531 | 532 | // запишем настройки в флэш память 533 | ElfWriteSettings(calend->proc->index_listed, &calend_opt, OPT_OFFSET_CALEND_OPT, sizeof(struct calend_opt_)); 534 | } 535 | 536 | // продлить таймер выхода при бездействии через INACTIVITY_PERIOD с 537 | set_update_period(1, INACTIVITY_PERIOD); 538 | break; 539 | }; 540 | 541 | case GESTURE_SWIPE_RIGHT: // свайп направо 542 | case GESTURE_SWIPE_LEFT: { // справа налево 543 | 544 | if ( get_left_side_menu_active()){ 545 | set_update_period(0,0); 546 | 547 | void* show_f = get_ptr_show_menu_func(); 548 | 549 | // запускаем dispatch_left_side_menu с параметром param в результате произойдет запуск соответствующего бокового экрана 550 | // при этом произойдет выгрузка данных текущего приложения и его деактивация. 551 | dispatch_left_side_menu(param); 552 | 553 | if ( get_ptr_show_menu_func() == show_f ){ 554 | // если dispatch_left_side_menu отработал безуспешно (листать некуда) то в show_menu_func по прежнему будет 555 | // содержаться наша функция show_calend_screen, тогда просто игнорируем этот жест 556 | 557 | // продлить таймер выхода при бездействии через INACTIVITY_PERIOD с 558 | set_update_period(1, INACTIVITY_PERIOD); 559 | return 0; 560 | } 561 | 562 | 563 | // если dispatch_left_side_menu отработал, то завершаем наше приложение, т.к. данные экрана уже выгрузились 564 | // на этом этапе уже выполняется новый экран (тот куда свайпнули) 565 | 566 | 567 | Elf_proc_* proc = get_proc_by_addr(main); 568 | proc->ret_f = NULL; 569 | 570 | elf_finish(main); // выгрузить Elf из памяти 571 | return 0; 572 | } else { // если запуск не из быстрого меню, обрабатываем свайпы по отдельности 573 | switch (gest->gesture){ 574 | case GESTURE_SWIPE_RIGHT: { // свайп направо 575 | return show_menu_animate(calend->ret_f, (unsigned int)show_calend_screen, ANIMATE_RIGHT); 576 | break; 577 | } 578 | case GESTURE_SWIPE_LEFT: { // справа налево 579 | // действие при запуске из меню и дальнейший свайп влево 580 | 581 | 582 | break; 583 | } 584 | } /// switch (gest->gesture) 585 | } 586 | 587 | break; 588 | }; // case GESTURE_SWIPE_LEFT: 589 | 590 | 591 | case GESTURE_SWIPE_UP: { // свайп вверх 592 | if ( calend->month < 12 ) 593 | calend->month++; 594 | else { 595 | calend->month = 1; 596 | calend->year++; 597 | } 598 | 599 | if ( (calend->year == datetime.year) && (calend->month == datetime.month) ) 600 | day = datetime.day; 601 | else 602 | day = 0; 603 | draw_month(day, calend->month, calend->year); 604 | repaint_screen_lines(1, 176); 605 | 606 | // продлить таймер выхода при бездействии через INACTIVITY_PERIOD с 607 | set_update_period(1, INACTIVITY_PERIOD); 608 | break; 609 | }; 610 | case GESTURE_SWIPE_DOWN: { // свайп вниз 611 | if ( calend->month > 1 ) 612 | calend->month--; 613 | else { 614 | calend->month = 12; 615 | calend->year--; 616 | } 617 | 618 | if ( (calend->year == datetime.year) && (calend->month == datetime.month) ) 619 | day = datetime.day; 620 | else 621 | day = 0; 622 | draw_month(day, calend->month, calend->year); 623 | repaint_screen_lines(1, 176); 624 | 625 | // продлить таймер выхода при бездействии через INACTIVITY_PERIOD с 626 | set_update_period(1, INACTIVITY_PERIOD); 627 | break; 628 | }; 629 | default:{ // что-то пошло не так... 630 | break; 631 | }; 632 | 633 | } 634 | 635 | 636 | return result; 637 | }; 638 | --------------------------------------------------------------------------------