// // Function: spotCommonInit // // Draw static Spotfire form visualization layout template // void spotCommonInit(char *label, u08 mode) { u08 i; char *sliderLabel; // Either clear everything or only the chart area if (mode == DRAW_INIT_PARTIAL) { u08 pxDone; // Partial init: clear only the chart area glcdFillRectangle(0, 16, 100, 48, mcBgColor); // Visualization title bar pxDone = glcdPutStr2(2, 9, FONT_5X5P, label, mcFgColor); if (pxDone + 2 < AD_X_START) glcdFillRectangle(pxDone + 2, 9, AD_X_START - pxDone - 2, 5, mcBgColor); } else { // Full init: start from scratch // Draw main lines for menu bar, vis title bar and filter panel glcdFillRectangle(0, 7, GLCD_XPIXELS, 1, mcFgColor); glcdFillRectangle(0, 15, GLCD_XPIXELS, 1, mcFgColor); glcdFillRectangle(101, 7, 1, GLCD_YPIXELS - 7, mcFgColor); // Init the Menu bar menuBarId = 255; spotMenuBarUpdate(); // Init the visualization Title bar label glcdPutStr2(2, 9, FONT_5X5P, label, mcFgColor); // Filter panel label glcdPutStr2(104, 9, FONT_5X5P, "FILTERS", mcFgColor); // There are three filter sliders; hour + min + sec for (i = 0; i <= 2; i++) { if (i == 0) sliderLabel = animHour; else if (i == 1) sliderLabel = animMin; else sliderLabel = animSec; // Paint filter slider glcdPutStr2(FP_X_START, FP_Y_START + i * FP_Y_OFFSET_SIZE, FONT_5X5P, sliderLabel, mcFgColor); glcdRectangle(FP_X_START + FP_RF_X_OFFSET, FP_Y_START + i * FP_Y_OFFSET_SIZE + FP_RF_Y_OFFSET, FP_RF_WIDTH, FP_RF_HEIGHT, mcFgColor); glcdFillRectangle(FP_X_START + FP_RS_X_OFFSET, FP_Y_START + i * FP_Y_OFFSET_SIZE + FP_RS_Y_OFFSET, FP_RS_WIDTH, FP_RS_HEIGHT, mcFgColor); } } }
// // Function: spotMenuBarUpdate // // Put a (not so special) header in a Spotfire clock menu bar // static void spotMenuBarUpdate(void) { // Only get a new menu bar when the date has changed or when we're // initializing if (mcClockDateEvent == GLCD_TRUE || mcClockInit == GLCD_TRUE) { uint8_t i = 1; uint8_t posX; menuBarDriver_t *mbDriver = menuBarDriver; // Find the new menu bar while (i < sizeof(menuBarDriver) / sizeof(menuBarDriver_t)) { if (mcClockNewDD == mbDriver->day && mcClockNewDM == mbDriver->month) break; i++; mbDriver++; } // Only update the menu bar if it has changed if (menuBarId != i) { DEBUG(putstring("Menu bar Id -> ")); DEBUG(uart_putw_dec(i)); DEBUG(putstring_nl("")); // Sync new menu bar menuBarId = i; // Get starting position on x axis if (mbDriver->barText == MBAR_TXT_LEFT) { // Text is to be started at left (with a small align indent) posX = 2; } else { // Text is to be centered posX = glcdGetWidthStr(FONT_5X5P, mbDriver->msg1); if (mbDriver->msg2 != 0) posX = posX + glcdGetWidthStr(FONT_5X5P, mbDriver->msg2); posX = (GLCD_XPIXELS - posX + 1) / 2; } // Clear the current bar glcdFillRectangle(0, 0, GLCD_XPIXELS, 7, mcBgColor); // Print the first and optionally second msg string posX = posX + glcdPutStr2(posX, 1, FONT_5X5P, mbDriver->msg1, mcFgColor); if (mbDriver->msg2 != 0) glcdPutStr2(posX, 1, FONT_5X5P, mbDriver->msg2, mcFgColor); } } }
// // Function: spotAxisInit // // Paint x/y-axis lines and labels in a Spotfire clock // void spotAxisInit(u08 clockId) { u08 i; u08 xs, xh, y; if (clockId == CHRON_BARCHART || clockId == CHRON_CASCADE || clockId == CHRON_LINECHART) { // Draw x/y-axis lines glcdFillRectangle(8, 23, 1, 34, mcFgColor); glcdFillRectangle(9, 56, 83, 1, mcFgColor); // Draw y-axis value 10 markers for (i = 24; i <= 54; i = i + 5) glcdDot(7, i, mcFgColor); } // Draw clock dependent things and setup coordinates for axis labels if (clockId == CHRON_BARCHART) { // Barchart glcdDot(37, 57, mcFgColor); glcdDot(64, 57, mcFgColor); xs = 72; xh = 16; y=58; } else if (clockId == CHRON_CASCADE || clockId == CHRON_LINECHART) { // Cascade or linechart xs = 75; xh = 13; y = 58; } else if (clockId == CHRON_TRAFLIGHT) { // Trafficlight xs = 78; xh = 10; y = 58; } else if (clockId == CHRON_THERMOMETER) { // Thermometer xs = 78; xh = 10; y = 59; } else // clockId == CHRON_SPEEDDIAL || clockId == CHRON_PIECHART { // Speeddial or piechart xs = 78; xh = 10; y = 54; } // Draw the axis labels glcdPutStr2(xs, y, FONT_5X5P, animSec, mcFgColor); glcdPutStr2(44, y, FONT_5X5P, animMin, mcFgColor); glcdPutStr2(xh, y, FONT_5X5P, animHour, mcFgColor); }
// // Function: spotBarUpdate // // Update a single bar (used in Spotfire bar chart and cascade) // void spotBarUpdate(u08 x, u08 width, u08 oldVal, u08 newVal, s08 valXOffset, u08 fillType) { u08 oldBarHeight; u08 newBarHeight; char barValue[3]; // See if there's any need to update a bar if (oldVal == newVal && mcClockInit == GLCD_FALSE) return; // Get height of old bar and new bar oldBarHeight = (u08)((SPOT_BAR_HEIGHT_MAX / (float)SPOT_BAR_VAL_STEPS) * oldVal + 0.5); newBarHeight = (u08)((SPOT_BAR_HEIGHT_MAX / (float)SPOT_BAR_VAL_STEPS) * newVal + 0.5); // If there are no changes in barheight there's no need to repaint the bar if (oldBarHeight != newBarHeight || mcClockInit == GLCD_TRUE) { // Paint new bar if (fillType == FILL_BLANK) { // A FILL_BLANK is in fact drawing the outline of the bar first and // then fill it with blank glcdRectangle(x, SPOT_BAR_Y_START - newBarHeight, width, newBarHeight + 1, mcFgColor); if (newBarHeight > 1) glcdFillRectangle2(x + 1, SPOT_BAR_Y_START - newBarHeight + 1, width - 2, newBarHeight - 1, ALIGN_TOP, fillType, mcFgColor); } else { glcdFillRectangle2(x, SPOT_BAR_Y_START - newBarHeight, width, newBarHeight + 1, ALIGN_BOTTOM, fillType, mcFgColor); } } // Add the bar value (depending on bar value font size) animValToStr(newVal, barValue); glcdPutStr2(x + valXOffset, SPOT_BAR_Y_START - newBarHeight + SPOT_BAR_VAL_Y_OFFSET, FONT_5X7N, barValue, mcFgColor); // Clear the first line between the bar and the bar value glcdFillRectangle(x, SPOT_BAR_Y_START - newBarHeight - 1, width, 1, mcBgColor); // Clear the space left and right of the bar value glcdFillRectangle(x, SPOT_BAR_Y_START - newBarHeight + SPOT_BAR_VAL_Y_OFFSET, valXOffset, -SPOT_BAR_VAL_Y_OFFSET - 1, mcBgColor); glcdFillRectangle(x + width - valXOffset + 1, SPOT_BAR_Y_START - newBarHeight + SPOT_BAR_VAL_Y_OFFSET, valXOffset - 1, -SPOT_BAR_VAL_Y_OFFSET - 1, mcBgColor); // Clear what was above it (if any) if (oldBarHeight > newBarHeight) glcdFillRectangle(x, SPOT_BAR_Y_START - oldBarHeight + SPOT_BAR_VAL_Y_OFFSET, width, oldBarHeight - newBarHeight, mcBgColor); }
// // Function: analogAlarmAreaUpdate // // Draw update in analog clock alarm area // void analogAlarmAreaUpdate(void) { u08 inverseAlarmArea = GLCD_FALSE; u08 newAlmDisplayState = GLCD_FALSE; if ((mcCycleCounter & 0x0F) >= 8) newAlmDisplayState = GLCD_TRUE; if (mcUpdAlarmSwitch == GLCD_TRUE) { if (mcAlarmSwitch == ALARM_SWITCH_ON) { // Show alarm time in small clock s08 dxM, dyM, dxH, dyH; float radM, radH; // Prepare the analog alarm clock radM = (2L * M_PI / ANA_SECMIN_STEPS) * mcAlarmM; dxM = (s08)(sin(radM) * ANA_ALARM_MIN_RADIUS); dyM = (s08)(-cos(radM) * ANA_ALARM_MIN_RADIUS); radH = (2L * M_PI / ANA_HOUR_STEPS) * (mcAlarmH % 12) + (2L * M_PI / ANA_SECMIN_STEPS / ANA_HOUR_STEPS) * mcAlarmM; dxH = (s08)(sin(radH) * ANA_ALARM_HOUR_RADIUS); dyH = (s08)(-cos(radH) * ANA_ALARM_HOUR_RADIUS); // Clear date area glcdFillRectangle(ANA_DATE_X_START, ANA_DATE_Y_START, ANA_DATE_X_SIZE, 5, mcBgColor); // Show the alarm time glcdCircle2(ANA_ALARM_X_START, ANA_ALARM_Y_START, ANA_ALARM_RADIUS, CIRCLE_FULL, mcFgColor); glcdLine(ANA_ALARM_X_START, ANA_ALARM_Y_START, ANA_ALARM_X_START + dxM, ANA_ALARM_Y_START + dyM, mcFgColor); glcdLine(ANA_ALARM_X_START, ANA_ALARM_Y_START, ANA_ALARM_X_START + dxH, ANA_ALARM_Y_START + dyH, mcFgColor); } else { // Show date u08 pxDone = 0; char msg[4] = {0}; // Clear alarm area glcdFillRectangle(ANA_ALARM_X_START - ANA_ALARM_RADIUS - 1, ANA_ALARM_Y_START - ANA_ALARM_RADIUS - 1, ANA_ALARM_RADIUS * 2 + 3, ANA_ALARM_RADIUS * 2 + 3, mcBgColor); mcU8Util1 = GLCD_FALSE; // Show the date char *s1, *s2; #ifdef DATE_MONTHDAY s1 = (char *)months[mcClockNewDM - 1]; s2 = msg; msg[0] = ' '; animValToStr(mcClockNewDD, &(msg[1])); #else s1 = msg; s2 = (char *)months[mcClockNewDM - 1]; animValToStr(mcClockNewDD, msg); msg[2] = ' '; #endif pxDone = glcdPutStr2(ANA_DATE_X_START, ANA_DATE_Y_START, FONT_5X5P, s1, mcFgColor) + ANA_DATE_X_START; pxDone = pxDone + glcdPutStr2(pxDone, ANA_DATE_Y_START, FONT_5X5P, s2, mcFgColor) - ANA_DATE_X_START; if (pxDone <= ANA_DATE_X_SIZE) glcdFillRectangle(ANA_DATE_X_START + pxDone, ANA_DATE_Y_START, ANA_DATE_X_SIZE - pxDone + 1, FILL_BLANK, mcBgColor); } } if (mcAlarming == GLCD_TRUE) { // Blink alarm area when we're alarming or snoozing if (newAlmDisplayState != mcU8Util1) { inverseAlarmArea = GLCD_TRUE; mcU8Util1 = newAlmDisplayState; } } else { // Reset inversed alarm area when alarming has stopped if (mcU8Util1 == GLCD_TRUE) { inverseAlarmArea = GLCD_TRUE; mcU8Util1 = GLCD_FALSE; } } // Inverse the alarm area if needed if (inverseAlarmArea == GLCD_TRUE) glcdFillRectangle2(ANA_ALARM_X_START - ANA_ALARM_RADIUS - 1, ANA_ALARM_Y_START - ANA_ALARM_RADIUS - 1, ANA_ALARM_RADIUS * 2 + 3, ANA_ALARM_RADIUS * 2 + 3, ALIGN_AUTO, FILL_INVERSE, mcBgColor); }