NXWidgets: chexcalculator.cxx Source File

NXWidgets 1.19

chexcalculator.cxx
Go to the documentation of this file.
1 /********************************************************************************************
2 * NxWidgets/nxwm/src/chexcalculator.cxx
3 *
4 * Copyright (C) 2012 Gregory Nutt. All rights reserved.
5 * Author: Gregory Nutt <gnutt@nuttx.org>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
18 * me be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ********************************************************************************************/
35
36 /********************************************************************************************
37 * Included Files
38 ********************************************************************************************/
39
40 #include <nuttx/config.h>
41
42 #include <cstdio>
43 #include <debug.h>
44
45 #include "cwidgetcontrol.hxx"
46
47 #include "nxwmconfig.hxx"
48 #include "nxwmglyphs.hxx"
49 #include "chexcalculator.hxx"
50
51 /********************************************************************************************
52 * Pre-Processor Definitions
53 ********************************************************************************************/
54
55 /********************************************************************************************
56 * Private Types
57 ********************************************************************************************/
58
59 /********************************************************************************************
60 * Private Data
61 ********************************************************************************************/
62
63 namespace NxWM
64 {
65 /**
66 * This enumeration value describes a key
67 */
68
69 enum EKeyType
70 {
71 KEY_NONE = 0, // Used to represent no pending operation
72
73 // Values: {0-9, A-F}
74
75 KEY_VALUE, // Key is a value
76
77 // Unary operators
78
79 KEY_NOT, // 1's complement
80 KEY_NEGATE, // 2's complement
81
82 // Binary operators
83
84 KEY_XOR, // Exclusive OR
85 KEY_DIVIDE, // Division
86 KEY_RSH, // Right shift
87 KEY_LSH, // Left shift
88 KEY_MULTIPLY, // Multiplication
89 KEY_AND, // Bit-wise AND
90 KEY_OR, // Bit-wise OR
91 KEY_MINUS, // Subtraction
92 KEY_PLUS, // Additions
93
94 // Special operations
95
96 KEY_EQUAL, // Equal/Enter key
97
98 KEY_DECIMAL, // Decimal mode
99 KEY_HEXADECIMAL, // Hexadecimal mode
100
101 KEY_MRECALL, // Recall from memory
102 KEY_MPLUS, // Add to memory
103 KEY_MMINUS, // Subtract from memory
104
105 KEY_MCLR, // Clear memory
106 KEY_CLRENTRY, // Clear entry
107 KEY_CLR // Clear all
108 };
109
110 /**
111 * This structure value describes a key
112 */
113
114 struct SKeyDesc
115 {
116 uint16_t hexMode : 1; // Key applies in hex mode
117 uint16_t decMode : 1; // Key applies in decimal mode
118 uint16_t keyType : 5; // Describes the key (see enum EKeyType)
119 uint16_t value : 4; // Value (if the key has an associated value)
120 };
121
122 /**
123 * This array provides the possible labels for each key
124 */
125
126 static FAR const char *g_labels[NXWM_HEXCALCULATOR_NCOLUMNS*NXWM_HEXCALCULATOR_NROWS] =
127 {
128 "MR", "M+", "M-", "MC", "CE", "C",
129 "A", "B", "C", "D", "E", "F",
130 "NOT", "XOR", "7", "8", "9", "/",
131 "RSH", "LSH", "4", "5", "6", "*",
132 "AND", "OR", "1", "2", "3", "-",
133 "DEC", "HEX", "+/-", "0", "=", "+"
134 };
135
136 /**
137 * This array manages the behavior when each key is pressed
138 */
139
140 static struct SKeyDesc g_keyDesc[NXWM_HEXCALCULATOR_NCOLUMNS*NXWM_HEXCALCULATOR_NROWS] =
141 {
142 {1, 1, KEY_MRECALL, 0},
143 {1, 1, KEY_MPLUS, 0},
144 {1, 1, KEY_MMINUS, 0},
145 {1, 1, KEY_MCLR, 0},
146 {1, 1, KEY_CLRENTRY, 0},
147 {1, 1, KEY_CLR, 0},
148
149 {1, 0, KEY_VALUE, 10},
150 {1, 0, KEY_VALUE, 11},
151 {1, 0, KEY_VALUE, 12},
152 {1, 0, KEY_VALUE, 13},
153 {1, 0, KEY_VALUE, 14},
154 {1, 0, KEY_VALUE, 15},
155
156 {1, 0, KEY_NOT, 0},
157 {1, 0, KEY_XOR, 0},
158 {1, 1, KEY_VALUE, 7},
159 {1, 1, KEY_VALUE, 8},
160 {1, 1, KEY_VALUE, 9},
161 {1, 1, KEY_DIVIDE, 0},
162
163 {1, 0, KEY_RSH, 0},
164 {1, 0, KEY_LSH, 0},
165 {1, 1, KEY_VALUE, 4},
166 {1, 1, KEY_VALUE, 5},
167 {1, 1, KEY_VALUE, 6},
168 {1, 1, KEY_MULTIPLY, 0},
169
170 {1, 0, KEY_AND, 0},
171 {1, 0, KEY_OR, 0},
172 {1, 1, KEY_VALUE, 1},
173 {1, 1, KEY_VALUE, 2},
174 {1, 1, KEY_VALUE, 3},
175 {1, 1, KEY_MINUS, 0},
176
177 {1, 0, KEY_DECIMAL, 0},
178 {0, 1, KEY_HEXADECIMAL, 0},
179 {1, 1, KEY_NEGATE, 0},
180 {1, 1, KEY_VALUE, 0},
181 {1, 1, KEY_EQUAL, 0},
182 {1, 1, KEY_PLUS, 0}
183 };
184 }
185
186 /********************************************************************************************
187 * Private Functions
188 ********************************************************************************************/
189
190 /********************************************************************************************
191 * CHexCalculator Method Implementations
192 ********************************************************************************************/
193
194 extern const struct NXWidgets::SRlePaletteBitmap CONFIG_NXWM_HEXCALCULATOR_ICON;
195
196 using namespace NxWM;
197
198 /**
199 * CHexCalculator constructor
200 *
201 * @param window. The application window
202 */
203
204 CHexCalculator::CHexCalculator(CTaskbar *taskbar, CApplicationWindow *window)
205 {
206 // Save the constructor data
207
208 m_taskbar = taskbar;
209 m_window = window;
210
211 // Nullify widgets that will be instantiated when the window is started
212
213 m_keypad = (NXWidgets::CButtonArray *)0;
214 m_text = (NXWidgets::CLabel *)0;
215 m_font = (NXWidgets::CNxFont *)0;
216
217 // Reset other values
218
219 m_accum = 0; // The accumulator is initially zero
220 m_memory = 0; // No value in memory
221 m_high.operation = (uint8_t)KEY_NONE; // No pending high precedence operation
222 m_high.value = 0;
223 m_low.operation = (uint8_t)KEY_NONE; // No pending high precedence operation
224 m_low.value = 0;
225 m_hexMode = false; // Decimal mode
226 m_result = false; // Accumulator does not hot a result
227
228 // Add our personalized window label
229
230 NXWidgets::CNxString myName = getName();
231 window->setWindowLabel(myName);
232
233 // Add our callbacks with the application window
234
235 window->registerCallbacks(static_cast<IApplicationCallback *>(this));
236
237 // Set the geometry of the calculator
238
239 setGeometry();
240 }
241
242 /**
243 * CHexCalculator destructor
244 *
245 * @param window. The application window
246 */
247
248 CHexCalculator::~CHexCalculator(void)
249 {
250 // Destroy widgets
251
252 if (m_text)
253 {
254 delete m_text;
255 }
256
257 if (m_keypad)
258 {
259 delete m_keypad;
260 }
261
262 if (m_font)
263 {
264 delete m_font;
265 }
266
267 // Although we didn't create it, we are responsible for deleting the
268 // application window
269
270 delete m_window;
271 }
272
273 /**
274 * Each implementation of IApplication must provide a method to recover
275 * the contained CApplicationWindow instance.
276 */
277
278 IApplicationWindow *CHexCalculator::getWindow(void) const
279 {
280 return static_cast<IApplicationWindow*>(m_window);
281 }
282
283 /**
284 * Get the icon associated with the application
285 *
286 * @return An instance if IBitmap that may be used to rend the
287 * application's icon. This is an new IBitmap instance that must
288 * be deleted by the caller when it is no long needed.
289 */
290
291 NXWidgets::IBitmap *CHexCalculator::getIcon(void)
292 {
293 NXWidgets::CRlePaletteBitmap *bitmap =
294 new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_HEXCALCULATOR_ICON);
295
296 return bitmap;
297 }
298
299 /**
300 * Get the name string associated with the application
301 *
302 * @return A copy if CNxString that contains the name of the application.
303 */
304
305 NXWidgets::CNxString CHexCalculator::getName(void)
306 {
307 return NXWidgets::CNxString("Hex Calculator");
308 }
309
310 /**
311 * Start the application (perhaps in the minimized state).
312 *
313 * @return True if the application was successfully started.
314 */
315
316 bool CHexCalculator::run(void)
317 {
318 // Create the widgets (if we have not already done so)
319
320 if (!m_keypad)
321 {
322 // Create the widgets
323
324 if (!createCalculator())
325 {
326 gerr("ERROR: Failed to create widgets\n");
327 return false;
328 }
329
330 // Apply initial labels
331
332 labelKeypad();
333 }
334
335 return true;
336 }
337
338 /**
339 * Stop the application.
340 */
341
342 void CHexCalculator::stop(void)
343 {
344 // Just disable further drawing
345
346 m_keypad->disableDrawing();
347 m_keypad->setRaisesEvents(false);
348
349 m_text->disableDrawing();
350 }
351
352 /**
353 * Destroy the application and free all of its resources. This method
354 * will initiate blocking of messages from the NX server. The server
355 * will flush the window message queue and reply with the blocked
356 * message. When the block message is received by CWindowMessenger,
357 * it will send the destroy message to the start window task which
358 * will, finally, safely delete the application.
359 */
360
361 void CHexCalculator::destroy(void)
362 {
363 // Make sure that the widgets are stopped
364
365 stop();
366
367 // Block any further window messages
368
369 m_window->block(this);
370 }
371
372 /**
373 * The application window is hidden (either it is minimized or it is
374 * maximized, but not at the top of the hierarchy
375 */
376
377 void CHexCalculator::hide(void)
378 {
379 // Disable drawing and events
380
381 stop();
382 }
383
384 /**
385 * Redraw the entire window. The application has been maximized or
386 * otherwise moved to the top of the hierarchy. This method is call from
387 * CTaskbar when the application window must be displayed
388 */
389
390 void CHexCalculator::redraw(void)
391 {
392 // Get the widget control associated with the application window
393
394 NXWidgets::CWidgetControl *control = m_window->getWidgetControl();
395
396 // Get the CCGraphicsPort instance for this window
397
398 NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
399
400 // Fill the entire window with the background color
401
402 port->drawFilledRect(0, 0, m_windowSize.w, m_windowSize.h,
403 CONFIG_NXWM_HEXCALCULATOR_BACKGROUNDCOLOR);
404
405 // Enable and redraw widgets
406
407 m_keypad->enableDrawing();
408 m_keypad->redraw();
409 m_keypad->setRaisesEvents(true);
410
411 m_text->enableDrawing();
412 m_text->redraw();
413 }
414
415 /**
416 * Report of this is a "normal" window or a full screen window. The
417 * primary purpose of this method is so that window manager will know
418 * whether or not it show draw the task bar.
419 *
420 * @return True if this is a full screen window.
421 */
422
423 bool CHexCalculator::isFullScreen(void) const
424 {
425 return m_window->isFullScreen();
426 }
427
428 /**
429 * Select the geometry of the calculator given the current window size.
430 */
431
432 void CHexCalculator::setGeometry(void)
433 {
434 // Recover the NXTK window instance contained in the application window
435
436 NXWidgets::INxWindow *window = m_window->getWindow();
437
438 // Get the size of the window
439
440 (void)window->getSize(&m_windowSize);
441
442 // Pick a height and width of a button to fill the entire window.
443 // For the height, we will assume that the text window is 1.5 times
444 // as high as a button
445
446 m_buttonSize.w = m_windowSize.w / NXWM_HEXCALCULATOR_NCOLUMNS;
447 m_buttonSize.h = (m_windowSize.h << 1) / (2 * NXWM_HEXCALCULATOR_NROWS + 3);
448
449 // Limit aspect ratio. (1) Button should no be taller than it is wide,
450 // (2) Button should be no more than twice as wide as it is tall.
451
452 if (m_buttonSize.h > m_buttonSize.w)
453 {
454 m_buttonSize.h = m_buttonSize.w;
455 }
456 else if (m_buttonSize.w > (m_buttonSize.h << 1))
457 {
458 m_buttonSize.w = (m_buttonSize.h << 1);
459 }
460
461 // Get the size of the entry calculator m_keypad
462
463 m_keypadSize.w = NXWM_HEXCALCULATOR_NCOLUMNS * m_buttonSize.w;
464 m_keypadSize.h = NXWM_HEXCALCULATOR_NROWS * m_buttonSize.h;
465
466 // Get the size of the text box. Same width as the m_keypad
467
468 m_textSize.w = m_keypadSize.w;
469 m_textSize.h = m_windowSize.h - m_keypadSize.h;
470
471 // Limit the height of the text box to twice the height of a button.
472
473 if (m_textSize.h > (m_buttonSize.h << 1))
474 {
475 m_textSize.h = (m_buttonSize.h << 1);
476 }
477
478 // Pick an X/Y position such that the m_keypad+textbox will be centered
479 // in the display
480
481 struct nxgl_point_s calculatorPos;
482 calculatorPos.x = (m_windowSize.w - m_keypadSize.w) >> 1;
483 calculatorPos.y = (m_windowSize.h - m_textSize.h - m_keypadSize.h) >> 1;
484
485 // Now pick the set of the text box and the m_keypad
486
487 m_textPos.x = calculatorPos.x;
488 m_textPos.y = calculatorPos.y;
489
490 m_keypadPos.x = calculatorPos.x;
491 m_keypadPos.y = calculatorPos.y + m_textSize.h;
492 }
493
494 /**
495 * Create the calculator widgets. Only start as part of the applicaiton
496 * start method.
497 */
498
499 bool CHexCalculator::createCalculator(void)
500 {
501 // Select a font for the calculator
502
503 m_font = new NXWidgets::CNxFont((nx_fontid_e)CONFIG_NXWM_HEXCALCULATOR_FONTID,
504 CONFIG_NXWM_DEFAULT_FONTCOLOR,
505 CONFIG_NXWM_TRANSPARENT_COLOR);
506 if (!m_font)
507 {
508 gerr("ERROR failed to create font\n");
509 return false;
510 }
511
512 // Get the widget control associated with the application window
513
514 NXWidgets::CWidgetControl *control = m_window->getWidgetControl();
515
516 // Create the button array
517
518 m_keypad = new NXWidgets::CButtonArray(control,
519 m_keypadPos.x, m_keypadPos.y,
520 NXWM_HEXCALCULATOR_NCOLUMNS,
521 NXWM_HEXCALCULATOR_NROWS,
522 m_buttonSize.w, m_buttonSize.h);
523 if (!m_keypad)
524 {
525 gerr("ERROR: Failed to create CButtonArray\n");
526 return false;
527 }
528
529 // Disable drawing and events until we are asked to redraw the window
530
531 m_keypad->disableDrawing();
532 m_keypad->setRaisesEvents(false);
533
534 // Select the font
535
536 m_keypad->setFont(m_font);
537
538 // Register to receive events from the keypad
539
540 m_keypad->addWidgetEventHandler(this);
541
542 // Create a label to show the accumulator. A simple label is used
543 // because the power of a text box is un-necessary in this application.
544
545 m_text = new NXWidgets::CLabel(control,
546 m_textPos.x, m_textPos.y,
547 m_textSize.w, m_textSize.h,
548 "0");
549 if (!m_text)
550 {
551 gerr("ERROR: Failed to create CLabel\n");
552 return false;
553 }
554
555 // Align text on the left
556
557 m_text->setTextAlignmentHoriz(NXWidgets::CLabel::TEXT_ALIGNMENT_HORIZ_RIGHT);
558
559 // Disable drawing and events until we are asked to redraw the window
560
561 m_text->disableDrawing();
562 m_text->setRaisesEvents(false);
563
564 // Select the font
565
566 m_text->setFont(m_font);
567 return true;
568 }
569
570 /**
571 * Applies labels to the keys.
572 */
573
574 void CHexCalculator::labelKeypad(void)
575 {
576 // Make sure that drawing is disabled from this operation
577
578 bool isEnabled = m_keypad->isDrawingEnabled();
579 m_keypad->disableDrawing();
580
581 // Add the labels to each button.
582
583 for (int j = 0; j < NXWM_HEXCALCULATOR_NROWS; j++)
584 {
585 for (int i = 0; i < NXWM_HEXCALCULATOR_NCOLUMNS; i++)
586 {
587 int index = j * NXWM_HEXCALCULATOR_NCOLUMNS + i;
588
589 // What mode are we in? Does the button label appear in this mode?
590
591 FAR const char *label;
592 if ((m_hexMode && g_keyDesc[index].hexMode) ||
593 (!m_hexMode && g_keyDesc[index].decMode))
594 {
595 label = g_labels[index];
596 }
597 else
598 {
599 label = "";
600 }
601
602 // Set the text in the label
603
604 m_keypad->setText(i, j, label);
605 }
606 }
607
608 // Then redraw the display
609
610 if (isEnabled)
611 {
612 m_keypad->enableDrawing();
613 m_keypad->redraw();
614 }
615 }
616
617 /**
618 * Evaluate a binary operation. The result is left in m_accum.
619 *
620 * @param value1. The first value
621 * @param value2. The second value
622 *
623 * @return The result of the operation
624 */
625
626 int64_t CHexCalculator::evaluateBinaryOperation(uint8_t operation, int64_t value1, int64_t value2)
627 {
628 switch (operation)
629 {
630 case KEY_NONE: // Do nothing if there is no pending operation
631 return 0;
632
633 case KEY_XOR: // Exclusive OR
634 return value1 ^ value2;
635
636 case KEY_DIVIDE: // Division
637 return value1 / value2;
638
639 case KEY_RSH: // Right shift
640 return value1 >> value2;
641
642 case KEY_LSH: // Left shift
643 return value1 << value2;
644
645 case KEY_MULTIPLY: // Multiplication
646 return value1 * value2;
647
648 case KEY_AND: // Bit-wise AND
649 return value1 & value2;
650
651 case KEY_OR: // Bit-wise OR
652 return value1 | value2;
653
654 case KEY_MINUS: // Subtraction
655 return value1 - value2;
656
657 case KEY_PLUS: // Additions
658 return value1 + value2;
659
660 default:
661 gerr("ERROR: Unexpected pending operation %d\n", operation);
662 return 0;
663 }
664 }
665
666 /**
667 * Show the current value of the accumulator.
668 */
669
670 void CHexCalculator::updateText(void)
671 {
672 char buffer[24];
673
674 if (m_hexMode)
675 {
676 std::snprintf(buffer, 24, "%16llX", m_accum);
677 }
678 else
679 {
680 std::snprintf(buffer, 24, "%lld", m_accum);
681 }
682
683 // setText will perform the redraw as well
684
685 m_text->setText(buffer);
686 }
687
688 /**
689 * Called when the window minimize button is pressed.
690 */
691
692 void CHexCalculator::minimize(void)
693 {
694 m_taskbar->minimizeApplication(static_cast<IApplication*>(this));
695 }
696
697 /**
698 * Called when the window close button is pressed.
699 */
700
701 void CHexCalculator::close(void)
702 {
703 m_taskbar->stopApplication(static_cast<IApplication*>(this));
704 }
705
706 /**
707 * Handle a widget action event. For CButtonArray, this is a button pre-
708 * release event.
709 *
710 * @param e The event data.
711 */
712
713 void CHexCalculator::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
714 {
715 // A button should now be clicked
716
717 int column;
718 int row;
719
720 if (m_keypad->isButtonClicked(column, row))
721 {
722 // Handle the key according to its type
723
724 int index = row * NXWM_HEXCALCULATOR_NCOLUMNS + column;
725
726 // First, make sure that the keypress is valid in this mode
727
728 if ((m_hexMode && !g_keyDesc[index].hexMode) ||
729 (!m_hexMode && !g_keyDesc[index].decMode))
730 {
731 // Ignore the key in this mode
732
733 return;
734 }
735
736 // Process the keypress
737
738 bool result = false;
739 switch (g_keyDesc[index].keyType)
740 {
741 // Values: {0-9, A-F}
742
743 case KEY_VALUE: // Key is a value
744 {
745 // If the accumulator current holds the result of a previous
746 // operation, then start fresh
747
748 if (m_result)
749 {
750 m_accum = (uint64_t)g_keyDesc[index].value;
751 }
752
753 // Otherwise, add the new value to the accumulator. The way
754 // in which it is added depends on the mode
755
756 else if (m_hexMode)
757 {
758 m_accum <<= 4;
759 m_accum |= (uint64_t)g_keyDesc[index].value;
760 }
761 else
762 {
763 m_accum *= 10;
764 m_accum += (uint64_t)g_keyDesc[index].value;
765 }
766 updateText();
767 }
768 break;
769
770 // Unary operators
771
772 case KEY_NOT: // 1's complement
773 {
774 m_accum = ~m_accum;
775 updateText();
776 }
777 break;
778
779 case KEY_NEGATE: // 2's complement
780 {
781 m_accum = -m_accum;
782 updateText();
783 }
784 break;
785
786 // Low precedence Binary operators
787
788 case KEY_XOR: // Exclusive OR
789 case KEY_OR: // Bit-wise OR
790 case KEY_MINUS: // Subtraction
791 case KEY_PLUS: // Additions
792 {
793 // Is there a high precedence operation?
794
795 if (m_high.operation != (uint8_t)KEY_NONE)
796 {
797 m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum);
798 m_high.operation = (uint8_t)KEY_NONE;
799 m_high.value = 0;
800 }
801
802 // Is there a pending low precedence operation?
803
804 if (m_low.operation != (uint8_t)KEY_NONE)
805 {
806 m_accum = evaluateBinaryOperation(m_low.operation, m_low.value, m_accum);
807 }
808
809 // Save the new low precedence operation
810
811 m_low.operation = (uint8_t) g_keyDesc[index].keyType;
812 m_low.value = m_accum;
813
814 // Update the display with the value in the accumulator, but
815 // then clear the accumulator in preparation for the next input
816
817 updateText();
818 m_accum = 0;
819 }
820 break;
821
822 // High precedence Binary operators
823
824 case KEY_DIVIDE: // Division
825 case KEY_RSH: // Right shift
826 case KEY_LSH: // Left shift
827 case KEY_MULTIPLY: // Multiplication
828 case KEY_AND: // Bit-wise AND
829 {
830 // Is there a high precedence operation?
831
832 if (m_high.operation != (uint8_t)KEY_NONE)
833 {
834 m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum);
835 }
836
837 // Save the new high precedence operation
838
839 m_high.operation = (uint8_t) g_keyDesc[index].keyType;
840 m_high.value = m_accum;
841
842 // Update the display with the value in the accumulator, but
843 // then clear the accumulator in preparation for the next input
844
845 updateText();
846 m_accum = 0;
847 }
848 break;
849
850 // Special operations
851
852 case KEY_EQUAL: // Equal/Enter key
853 {
854 // Is there a high precedence operation?
855
856 if (m_high.operation != (uint8_t)KEY_NONE)
857 {
858 m_accum = evaluateBinaryOperation(m_high.operation, m_high.value, m_accum);
859 m_high.operation = (uint8_t)KEY_NONE;
860 m_high.value = 0;
861 }
862
863 // Is there a pending low precedence operation?
864
865 if (m_low.operation != (uint8_t)KEY_NONE)
866 {
867 m_accum = evaluateBinaryOperation(m_low.operation, m_low.value, m_accum);
868 m_low.operation = (uint8_t)KEY_NONE;
869 m_low.value = 0;
870 }
871
872 // Update the display with the value in the accumulator. Flag that
873 // this is a result meaning that (1) it can be used as an accumulator
874 // for the next operation, but new input values cannot be appended to it.
875
876 updateText();
877 result = true;
878 }
879 break;
880
881 case KEY_DECIMAL: // Decimal mode
882 {
883 if (m_hexMode)
884 {
885 m_hexMode = false;
886 labelKeypad();
887 updateText();
888 }
889 }
890 break;
891
892 case KEY_HEXADECIMAL: // Hexadecimal mode
893 {
894 if (!m_hexMode)
895 {
896 m_hexMode = true;
897 labelKeypad();
898 updateText();
899 }
900 }
901 break;
902
903 case KEY_MRECALL: // Recall from memory
904 {
905 m_accum = m_memory;
906 updateText();
907 }
908 break;
909
910 case KEY_MPLUS: // Add to memory
911 {
912 m_memory += m_accum;
913 }
914 break;
915
916 case KEY_MMINUS: // Subtract from memory
917 {
918 m_memory -= m_accum;
919 }
920 break;
921
922 case KEY_MCLR: // Clear memory
923 {
924 m_memory = 0;
925 }
926 break;
927
928 case KEY_CLRENTRY: // Clear entry
929 {
930 m_accum = 0;
931 updateText();
932 }
933 break;
934
935 case KEY_CLR: // Clear all
936 {
937 m_accum = 0;
938 m_high.operation = (uint8_t)KEY_NONE;
939 m_high.value = 0;
940 m_low.operation = (uint8_t)KEY_NONE;
941 m_low.value = 0;
942 updateText();
943 }
944 break;
945
946 case KEY_NONE:
947 default:
948 gerr("ERROR: Invalid key type %d\n", g_keyDesc[index].keyType);
949 break;
950 }
951
952 // Remember if the accumulator contains a special reault
953
954 m_result = result;
955 }
956 }
957
958 /**
959 * CHexCalculatorFactory Constructor
960 *
961 * @param taskbar. The taskbar instance used to terminate the console
962 */
963
964 CHexCalculatorFactory::CHexCalculatorFactory(CTaskbar *taskbar)
965 {
966 m_taskbar = taskbar;
967 }
968
969 /**
970 * Create a new instance of an CHexCalculator (as IApplication).
971 */
972
973 IApplication *CHexCalculatorFactory::create(void)
974 {
975 // Call CTaskBar::openFullScreenWindow to create a application window for
976 // the NxTerm application
977
978 CApplicationWindow *window = m_taskbar->openApplicationWindow();
979 if (!window)
980 {
981 gerr("ERROR: Failed to create CApplicationWindow\n");
982 return (IApplication *)0;
983 }
984
985 // Open the window (it is hot in here)
986
987 if (!window->open())
988 {
989 gerr("ERROR: Failed to open CApplicationWindow\n");
990 delete window;
991 return (IApplication *)0;
992 }
993
994 // Instantiate the application, providing the window to the application's
995 // constructor
996
997 CHexCalculator *hexCalculator = new CHexCalculator(m_taskbar, window);
998 if (!hexCalculator)
999 {
1000 gerr("ERROR: Failed to instantiate CHexCalculator\n");
1001 delete window;
1002 return (IApplication *)0;
1003 }
1004
1005 return static_cast<IApplication*>(hexCalculator);
1006 }
1007
1008 /**
1009 * Get the icon associated with the application
1010 *
1011 * @return An instance if IBitmap that may be used to rend the
1012 * application's icon. This is an new IBitmap instance that must
1013 * be deleted by the caller when it is no long needed.
1014 */
1015
1016 NXWidgets::IBitmap *CHexCalculatorFactory::getIcon(void)
1017 {
1018 NXWidgets::CRlePaletteBitmap *bitmap =
1019 new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_HEXCALCULATOR_ICON);
1020
1021 return bitmap;
1022 }
NxWM::CHexCalculator::close
void close(void)
Definition: chexcalculator.cxx:701
NxWM::CApplicationWindow
Definition: capplicationwindow.hxx:74
NxWM::KEY_MMINUS
Definition: chexcalculator.cxx:103
NxWM::KEY_HEXADECIMAL
Definition: chexcalculator.cxx:99
NxWM::KEY_LSH
Definition: chexcalculator.cxx:87
NxWM::SKeyDesc::keyType
uint16_t keyType
Definition: chexcalculator.cxx:118
NXWidgets::CWidgetControl::getGraphicsPort
CGraphicsPort * getGraphicsPort(void)
Definition: cwidgetcontrol.hxx:769
NxWM::SKeyDesc
Definition: chexcalculator.cxx:114
NXWidgets::CWidgetControl
Definition: cwidgetcontrol.hxx:95
NxWM::CHexCalculator::labelKeypad
void labelKeypad(void)
Definition: chexcalculator.cxx:574
NxWM::g_labels
static FAR const char * g_labels[NXWM_HEXCALCULATOR_NCOLUMNS *NXWM_HEXCALCULATOR_NROWS]
Definition: chexcalculator.cxx:126
NxWM::CHexCalculator::createCalculator
bool createCalculator(void)
Definition: chexcalculator.cxx:499
NxWM::KEY_NEGATE
Definition: chexcalculator.cxx:80
NxWM::KEY_VALUE
Definition: chexcalculator.cxx:75
NxWM::CHexCalculator::minimize
void minimize(void)
Definition: chexcalculator.cxx:692
NxWM::CHexCalculator::getWindow
IApplicationWindow * getWindow(void) const
Definition: chexcalculator.cxx:278
NxWM::KEY_EQUAL
Definition: chexcalculator.cxx:96
NXWidgets::CRlePaletteBitmap
Definition: crlepalettebitmap.hxx:100
NxWM::SKeyDesc::decMode
uint16_t decMode
Definition: chexcalculator.cxx:117
NxWM::CHexCalculatorFactory::create
IApplication * create(void)
Definition: chexcalculator.cxx:973
chexcalculator.hxx
NxWM::KEY_MPLUS
Definition: chexcalculator.cxx:102
NxWM::CHexCalculator::evaluateBinaryOperation
int64_t evaluateBinaryOperation(uint8_t operation, int64_t value1, int64_t value2)
Definition: chexcalculator.cxx:626
cwidgetcontrol.hxx
NxWM::KEY_MULTIPLY
Definition: chexcalculator.cxx:88
NxWM::CApplicationWindow::setWindowLabel
void setWindowLabel(NXWidgets::CNxString &appname)
Definition: capplicationwindow.cxx:475
NxWM::CHexCalculator::~CHexCalculator
~CHexCalculator(void)
Definition: chexcalculator.cxx:248
NxWM::CHexCalculatorFactory::getIcon
NXWidgets::IBitmap * getIcon(void)
Definition: chexcalculator.cxx:1016
NxWM::KEY_CLR
Definition: chexcalculator.cxx:107
NxWM::KEY_NONE
Definition: chexcalculator.cxx:71
NXWidgets::INxWindow::getSize
virtual bool getSize(FAR struct nxgl_size_s *pSize)=0
NxWM::KEY_NOT
Definition: chexcalculator.cxx:79
nxwmconfig.hxx
NxWM::KEY_PLUS
Definition: chexcalculator.cxx:92
NxWM::SKeyDesc::hexMode
uint16_t hexMode
Definition: chexcalculator.cxx:116
NxWM::KEY_MCLR
Definition: chexcalculator.cxx:105
nxwmglyphs.hxx
NXWidgets::CNxFont
Definition: cnxfont.hxx:70
NxWM
Definition: capplicationwindow.hxx:66
NxWM::KEY_MINUS
Definition: chexcalculator.cxx:91
NxWM::CHexCalculator::hide
void hide(void)
Definition: chexcalculator.cxx:377
NxWM::EKeyType
EKeyType
Definition: chexcalculator.cxx:69
NxWM::KEY_RSH
Definition: chexcalculator.cxx:86
NXWidgets::CGraphicsPort::drawFilledRect
void drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
Definition: cgraphicsport.cxx:280
NxWM::CHexCalculator::getName
NXWidgets::CNxString getName(void)
Definition: chexcalculator.cxx:305
NxWM::CHexCalculator::redraw
void redraw(void)
Definition: chexcalculator.cxx:390
NxWM::CHexCalculator::stop
void stop(void)
Definition: chexcalculator.cxx:342
NXWidgets::CButtonArray
Definition: cbuttonarray.hxx:77
NxWM::CTaskbar
Definition: ctaskbar.hxx:85
NxWM::CApplicationWindow::registerCallbacks
void registerCallbacks(IApplicationCallback *callback)
Definition: capplicationwindow.cxx:497
NxWM::CHexCalculator::isFullScreen
bool isFullScreen(void) const
Definition: chexcalculator.cxx:423
NxWM::g_keyDesc
static struct SKeyDesc g_keyDesc[NXWM_HEXCALCULATOR_NCOLUMNS *NXWM_HEXCALCULATOR_NROWS]
Definition: chexcalculator.cxx:140
NxWM::CHexCalculatorFactory::CHexCalculatorFactory
CHexCalculatorFactory(CTaskbar *taskbar)
Definition: chexcalculator.cxx:964
NXWidgets::CWidgetEventArgs
Definition: cwidgeteventargs.hxx:127
NxWM::KEY_MRECALL
Definition: chexcalculator.cxx:101
NxWM::KEY_CLRENTRY
Definition: chexcalculator.cxx:106
NxWM::CHexCalculator
Definition: chexcalculator.hxx:76
NxWM::IApplicationWindow
Definition: iapplicationwindow.hxx:95
NxWM::KEY_OR
Definition: chexcalculator.cxx:90
NxWM::IApplication
Definition: iapplication.hxx:70
NxWM::KEY_DIVIDE
Definition: chexcalculator.cxx:85
NxWM::KEY_AND
Definition: chexcalculator.cxx:89
NxWM::CHexCalculator::setGeometry
void setGeometry(void)
Definition: chexcalculator.cxx:432
NXWidgets::CNxString
Definition: cnxstring.hxx:121
NXWidgets::SRlePaletteBitmap
Definition: crlepalettebitmap.hxx:80
NXWidgets::CLabel
Definition: clabel.hxx:112
bitmap
static const NXWidgets::SRlePaletteBitmapEntry bitmap[]
Definition: glyph_mediaplayer24x24.cxx:85
NxWM::CHexCalculator::updateText
void updateText(void)
Definition: chexcalculator.cxx:670
NXWidgets::INxWindow
Definition: inxwindow.hxx:83
NxWM::CApplicationWindow::open
bool open(void)
Definition: capplicationwindow.cxx:166
NXWidgets::IBitmap
Definition: ibitmap.hxx:103
NxWM::CHexCalculator::CHexCalculator
CHexCalculator(CTaskbar *taskbar, CApplicationWindow *window)
Definition: chexcalculator.cxx:204
NxWM::CHexCalculator::destroy
void destroy(void)
Definition: chexcalculator.cxx:361
NxWM::CHexCalculator::handleActionEvent
void handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
Definition: chexcalculator.cxx:713
NXWidgets::CLabel::TEXT_ALIGNMENT_HORIZ_RIGHT
Definition: clabel.hxx:124
NxWM::KEY_DECIMAL
Definition: chexcalculator.cxx:98
NxWM::KEY_XOR
Definition: chexcalculator.cxx:84
NxWM::CHexCalculator::run
bool run(void)
Definition: chexcalculator.cxx:316
NxWM::CHexCalculator::getIcon
NXWidgets::IBitmap * getIcon(void)
Definition: chexcalculator.cxx:291
NXWidgets::CGraphicsPort
Definition: cgraphicsport.hxx:106
NxWM::SKeyDesc::value
uint16_t value
Definition: chexcalculator.cxx:119