summaryrefslogtreecommitdiff
path: root/apps/plugins/clock/clock_draw_analog.c
diff options
context:
space:
mode:
authorKevin Ferrare <kevin@rockbox.org>2007-08-04 03:01:46 +0000
committerKevin Ferrare <kevin@rockbox.org>2007-08-04 03:01:46 +0000
commit93b2f9fd447b73fff736d71826880ef9ac64bd94 (patch)
tree1a4f54016c312738d66fb9dd2348ea0ef14f1255 /apps/plugins/clock/clock_draw_analog.c
parentffbbc60f38ddc8aeadc9cea1102077e22ca84a1a (diff)
downloadrockbox-93b2f9fd447b73fff736d71826880ef9ac64bd94.zip
rockbox-93b2f9fd447b73fff736d71826880ef9ac64bd94.tar.gz
rockbox-93b2f9fd447b73fff736d71826880ef9ac64bd94.tar.bz2
rockbox-93b2f9fd447b73fff736d71826880ef9ac64bd94.tar.xz
Rewrote the clock plugin in a cleaner and more modular way so that it can scale on remote screens. Use left-right keys to change the type of clock displayed (analogic, digital, binary) and up/downto change the look of the clock
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14174 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/clock/clock_draw_analog.c')
-rw-r--r--apps/plugins/clock/clock_draw_analog.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/apps/plugins/clock/clock_draw_analog.c b/apps/plugins/clock/clock_draw_analog.c
new file mode 100644
index 0000000..1fd9877
--- /dev/null
+++ b/apps/plugins/clock/clock_draw_analog.c
@@ -0,0 +1,217 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
+ *
+ * Copyright (C) 2007 Copyright Kévin Ferrare based on Zakk Roberts's work
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "clock_draw_analog.h"
+#include "xlcd.h"
+#include "fixedpoint.h"
+#include "clock_bitmaps.h"
+#include "clock_bitmap_strings.h"
+
+#define ANALOG_SECOND_RADIUS(screen, round) \
+ ANALOG_MINUTE_RADIUS(screen, round)
+#define ANALOG_MINUTE_RADIUS(screen, round) \
+ (round?MIN(screen->height/2 -10, screen->width/2 -10):screen->height/2)
+#define ANALOG_HOUR_RADIUS(screen, round) \
+ (ANALOG_MINUTE_RADIUS(screen, round)/2)
+
+#define HOUR_ANGLE(hour, minute, second) (30*(hour) +(minute)/2)
+#define MINUTE_ANGLE(minute, second) (6*(minute)+(second)/10)
+#define SECOND_ANGLE(second) (6 * (second))
+
+void polar_to_cartesian(int a, int r, int* x, int* y){
+ *x = (sin_int(a) * r) >> 14;
+ *y = (sin_int(a-90) * r) >> 14;
+}
+
+void polar_to_cartesian_screen_centered(struct screen * display,
+ int a, int r, int* x, int* y){
+ polar_to_cartesian(a, r, x, y);
+ *x+=display->width/2;
+ *y+=display->height/2;
+}
+
+void angle_to_square(int square_width, int square_height,
+ int a, int* x, int* y){
+ a = (a+360-90)%360;
+ if(a>45 && a<=135){/* top line */
+ a-=45;
+ *x=square_width-(square_width*2*a)/90;
+ *y=square_height;
+ }else if(a>135 && a<=225){/* left line */
+ a-=135;
+ *x=-square_width;
+ *y=square_height-(square_height*2*a)/90;
+ }else if(a>225 && a<=315){/* bottom line */
+ a-=225;
+ *x=(square_width*2*a)/90-square_width;
+ *y=-square_height;
+ }else if(a>315 || a<=45){/* right line */
+ if(a>315)
+ a-=315;
+ else
+ a+=45;
+ *x=square_width;
+ *y=(square_height*2*a)/90-square_height;
+ }
+}
+
+void angle_to_square_screen_centered(struct screen * display,
+ int square_width, int square_height,
+ int a, int* x, int* y){
+ angle_to_square(square_width, square_height, a, x, y);
+ *x+=display->width/2;
+ *y+=display->height/2;
+}
+
+void draw_hand(struct screen* display, int angle,
+ int radius, int thickness, bool round){
+ int x1, y1; /* the longest */
+ int x2, y2, x3, y3; /* the base */
+ if(round){/* round clock */
+ polar_to_cartesian_screen_centered(display, angle,
+ radius, &x1, &y1);
+ }else{/* fullscreen clock, hands describes square motions */
+ int square_width, square_height;
+ /* radius is defined smallest between width and height */
+ square_height=radius;
+ square_width=(radius*display->width)/display->height;
+ angle_to_square_screen_centered(
+ display, square_width, square_height, angle, &x1, &y1);
+ }
+ polar_to_cartesian_screen_centered(display, (angle+120)%360,
+ radius/40+thickness, &x2, &y2);
+ polar_to_cartesian_screen_centered(display, (angle+240)%360,
+ radius/40+thickness, &x3, &y3);
+ xlcd_filltriangle_screen(display, x1, y1, x2, y2, x3, y3);
+}
+
+void draw_hands(struct screen* display, int hour, int minute, int second,
+ int thickness, bool round, bool draw_seconds){
+ if(draw_seconds){
+ draw_hand(display, SECOND_ANGLE(second),
+ ANALOG_SECOND_RADIUS(display, round), thickness, round);
+ }
+ draw_hand(display, MINUTE_ANGLE(minute, second),
+ ANALOG_MINUTE_RADIUS(display, round), thickness+2, round);
+ draw_hand(display, HOUR_ANGLE(hour, minute, second),
+ ANALOG_HOUR_RADIUS(display, round), thickness+2, round);
+}
+
+/*******************
+ * Analog clock mode
+ ******************/
+void analog_clock_draw(struct screen* display, struct time* time,
+ struct clock_settings* settings,
+ struct counter* counter,
+ int skin){
+ int i;
+ const struct picture* smalldigits_bitmaps =
+ &(smalldigits[display->screen_type]);
+ int hour=time->hour;
+ if(hour >= 12)
+ hour -= 12;
+
+ /* show_date */
+ /* show_digital_time*/
+
+ /* Crappy fake antialiasing (color LCDs only)!
+ * how this works is we draw a large mid-gray hr/min/sec hand,
+ * then the actual (slightly smaller) hand on top of those.
+ * End result: mid-gray edges to the black hands, smooths them out. */
+#ifdef HAVE_LCD_COLOR
+ if(display->is_color){
+ display->set_foreground(LCD_RGBPACK(100,110,125));
+ draw_hands(display, hour, time->minute, time->second, 2,
+ skin, settings->analog.show_seconds);
+ display->set_foreground(LCD_BLACK);
+ }
+#endif
+ draw_hands(display, hour, time->minute, time->second, 0, skin,
+ settings->analog.show_seconds);
+
+ if(settings->analog.show_border){
+ /* Draws square dots every 5 minutes */
+ int x, y;
+ int size=display->height/50;/* size of the square dots */
+ if(size%2)/* a pair number */
+ size++;
+ for(i=0; i < 60; i+=5){
+ if(skin){
+ polar_to_cartesian_screen_centered(display, MINUTE_ANGLE(i, 0),
+ ANALOG_MINUTE_RADIUS(display, skin), &x, &y);
+ }else{
+ angle_to_square_screen_centered(
+ display, display->width/2-size/2, display->height/2-size/2,
+ MINUTE_ANGLE(i, 0), &x, &y);
+ }
+ display->fillrect(x-size/2, y-size/2, size, size);
+ }
+ }
+
+ if(counter){
+ char buffer[10];
+ int second_str_w, hour_str_w, str_h;
+ struct time counter_time;
+ counter_get_elapsed_time(counter, &counter_time);
+ rb->snprintf(buffer, 10, "%02d:%02d",
+ counter_time.hour, counter_time.minute);
+ getstringsize(smalldigits_bitmaps, buffer, &hour_str_w, &str_h);
+ draw_string(display, smalldigits_bitmaps, buffer,
+ display->width-hour_str_w,
+ display->height-2*str_h);
+
+ rb->snprintf(buffer, 10, "%02d", counter_time.second);
+ getstringsize(smalldigits_bitmaps, buffer, &second_str_w, &str_h);
+ draw_string(display, smalldigits_bitmaps, buffer,
+ display->width-(hour_str_w+second_str_w)/2,
+ display->height-str_h);
+ }
+ if(settings->analog.show_date && settings->general.date_format!=NONE){
+ char buffer[10];
+ int year_str_w, monthday_str_w, str_h;
+ if(settings->general.date_format==ENGLISH){
+ rb->snprintf(buffer, 10, "%02d/%02d", time->month, time->day);
+ }else{
+ rb->snprintf(buffer, 10, "%02d/%02d", time->day, time->month);
+ }
+ getstringsize(smalldigits_bitmaps, buffer, &monthday_str_w, &str_h);
+ draw_string(display, smalldigits_bitmaps, buffer,
+ 0, display->height-2*str_h);
+ rb->snprintf(buffer, 10, "%04d", time->year);
+ getstringsize(smalldigits_bitmaps, buffer, &year_str_w, &str_h);
+ draw_string(display, smalldigits_bitmaps, buffer,
+ (monthday_str_w-year_str_w)/2, display->height-str_h);
+ }
+
+ /* Draw the cover over the center */
+ display->drawline((display->width/2)-1, (display->height/2)+3,
+ (display->width/2)+1, (display->height/2)+3);
+ display->drawline((display->width/2)-3, (display->height/2)+2,
+ (display->width/2)+3, (display->height/2)+2);
+ display->drawline((display->width/2)-4, (display->height/2)+1,
+ (display->width/2)+4, (display->height/2)+1);
+ display->drawline((display->width/2)-4, display->height/2,
+ (display->width/2)+4, display->height/2);
+ display->drawline((display->width/2)-4, (display->height/2)-1,
+ (display->width/2)+4, (display->height/2)-1);
+ display->drawline((display->width/2)-3, (display->height/2)-2,
+ (display->width/2)+3, (display->height/2)-2);
+ display->drawline((display->width/2)-1, (display->height/2)-3,
+ (display->width/2)+1, (display->height/2)-3);
+}