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 
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 
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 
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 
292 {
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 
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 
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 
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 
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 
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 
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 
424 {
425  return m_window->isFullScreen();
426 }
427 
428 /**
429  * Select the geometry of the calculator given the current window size.
430  */
431 
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 
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 
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 
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 
693 {
694  m_taskbar->minimizeApplication(static_cast<IApplication*>(this));
695 }
696 
697 /**
698  * Called when the window close button is pressed.
699  */
700 
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 
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 
965 {
966  m_taskbar = taskbar;
967 }
968 
969 /**
970  * Create a new instance of an CHexCalculator (as IApplication).
971  */
972 
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 
1017 {
1019  new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_HEXCALCULATOR_ICON);
1020 
1021  return bitmap;
1022 }
CGraphicsPort * getGraphicsPort(void)
static FAR const char * g_labels[NXWM_HEXCALCULATOR_NCOLUMNS *NXWM_HEXCALCULATOR_NROWS]
IApplicationWindow * getWindow(void) const
IApplication * create(void)
int64_t evaluateBinaryOperation(uint8_t operation, int64_t value1, int64_t value2)
void setWindowLabel(NXWidgets::CNxString &appname)
NXWidgets::IBitmap * getIcon(void)
virtual bool getSize(FAR struct nxgl_size_s *pSize)=0
void drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
NXWidgets::CNxString getName(void)
void registerCallbacks(IApplicationCallback *callback)
bool isFullScreen(void) const
static struct SKeyDesc g_keyDesc[NXWM_HEXCALCULATOR_NCOLUMNS *NXWM_HEXCALCULATOR_NROWS]
CHexCalculatorFactory(CTaskbar *taskbar)
static const NXWidgets::SRlePaletteBitmapEntry bitmap[]
CHexCalculator(CTaskbar *taskbar, CApplicationWindow *window)
void handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
NXWidgets::IBitmap * getIcon(void)