diff --git a/apps/hardware_test/Makefile b/apps/hardware_test/Makefile index 447f25a4d..01a46c665 100644 --- a/apps/hardware_test/Makefile +++ b/apps/hardware_test/Makefile @@ -2,6 +2,7 @@ app_objs += $(addprefix apps/hardware_test/,\ app.o\ arrow_view.o\ battery_test_controller.o\ + code_128b_view.o\ keyboard_test_controller.o\ keyboard_view.o\ led_test_controller.o\ @@ -11,6 +12,7 @@ app_objs += $(addprefix apps/hardware_test/,\ reset_controller.o\ screen_test_controller.o\ screen_test_controller.o\ + serial_number_controller.o\ usb_test_controller.o\ ) diff --git a/apps/hardware_test/app.cpp b/apps/hardware_test/app.cpp index 5c38922b8..a7ee45cd2 100644 --- a/apps/hardware_test/app.cpp +++ b/apps/hardware_test/app.cpp @@ -17,27 +17,48 @@ App::Descriptor * App::Snapshot::descriptor() { } App::App(Container * container, Snapshot * snapshot) : - ::App(container, snapshot, &m_keyboardController), - m_keyboardController(&m_modalViewController), - m_USBTestController(nullptr) + ::App(container, snapshot, &m_wizardViewController), + m_wizardViewController(&m_modalViewController) { } -ViewController * App::USBController() { - return &m_USBTestController; +App::WizardViewController::WizardViewController(Responder * parentResponder) : + BankViewController(parentResponder), + m_keyboardController(this), + m_screenTestController(this), + m_ledTestController(this), + m_batteryTestController(this), + m_USBTestController(this), + m_serialNumberController(this), + m_resetController(this) +{ } -int App::numberOfTimers() { - return firstResponder() == &m_USBTestController; +int App::WizardViewController::numberOfChildren() { + return 7; } -Timer * App::timerAtIndex(int i) { - assert(i == 0); - return &m_USBTestController; +ViewController * App::WizardViewController::childAtIndex(int i) { + ViewController * children[] = { + &m_keyboardController, + &m_screenTestController, + &m_ledTestController, + &m_batteryTestController, + &m_USBTestController, + &m_serialNumberController, + &m_resetController + }; + return children[i]; } -bool App::processEvent(Ion::Events::Event e) { - ::App::processEvent(e); +bool App::WizardViewController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OnOff) { + return false; + } + if (activeIndex() >= numberOfChildren()) { + return false; + } + setActiveIndex(activeIndex() + 1); return true; } diff --git a/apps/hardware_test/app.h b/apps/hardware_test/app.h index 3b49541ad..355a97bb5 100644 --- a/apps/hardware_test/app.h +++ b/apps/hardware_test/app.h @@ -2,8 +2,13 @@ #define HARDWARE_TEST_APP_H #include -#include "usb_test_controller.h" #include "keyboard_test_controller.h" +#include "screen_test_controller.h" +#include "led_test_controller.h" +#include "battery_test_controller.h" +#include "usb_test_controller.h" +#include "serial_number_controller.h" +#include "reset_controller.h" class AppsContainer; @@ -16,14 +21,25 @@ public: App * unpack(Container * container) override; Descriptor * descriptor() override; }; - ViewController * USBController(); - int numberOfTimers() override; - Timer * timerAtIndex(int i) override; - bool processEvent(Ion::Events::Event e) override; private: + class WizardViewController : public BankViewController { + public: + WizardViewController(Responder * parentResponder); + int numberOfChildren() override; + ViewController * childAtIndex(int i) override; + bool handleEvent(Ion::Events::Event event) override; + private: + KeyboardTestController m_keyboardController; + ScreenTestController m_screenTestController; + LEDTestController m_ledTestController; + BatteryTestController m_batteryTestController; + USBTestController m_USBTestController; + SerialNumberController m_serialNumberController; + ResetController m_resetController; + }; + App(Container * container, Snapshot * snapshot); - KeyboardTestController m_keyboardController; - USBTestController m_USBTestController; + WizardViewController m_wizardViewController; }; } diff --git a/apps/hardware_test/battery_test_controller.cpp b/apps/hardware_test/battery_test_controller.cpp index 2892e4410..597795403 100644 --- a/apps/hardware_test/battery_test_controller.cpp +++ b/apps/hardware_test/battery_test_controller.cpp @@ -23,9 +23,8 @@ View * BatteryTestController::view() { bool BatteryTestController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK) { if (strcmp(m_view.batteryStateTextView()->text(), k_batteryOKText) == 0) { - ModalViewController * modal = (ModalViewController *)parentResponder(); - App * a = (App *)app(); - modal->displayModalViewController(a->USBController(), 0.0f, 0.0f); + // Handled in WizardViewController + return false; } } updateBatteryState(Ion::Battery::voltage(), Ion::Battery::isCharging()); diff --git a/apps/hardware_test/code_128b_view.cpp b/apps/hardware_test/code_128b_view.cpp new file mode 100644 index 000000000..090708492 --- /dev/null +++ b/apps/hardware_test/code_128b_view.cpp @@ -0,0 +1,100 @@ +#include "code_128b_view.h" + +namespace HardwareTest { + +constexpr uint16_t patterns[] = {0x6CC, 0x66C, 0x666, 0x498, 0x48C, 0x44C, 0x4C8, 0x4C4, 0x464, 0x648, 0x644, 0x624, 0x59C, 0x4DC, 0x4CE, 0x5CC, 0x4EC, 0x4E6, 0x672, 0x65C, 0x64E, 0x6E4, 0x674, 0x76E, 0x74C, 0x72C, 0x726, 0x764, 0x734, 0x732, 0x6D8, 0x6C6, 0x636, 0x518, 0x458, 0x446, 0x588, 0x468, 0x462, 0x688, 0x628, 0x622, 0x5B8, 0x58E, 0x46E, 0x5D8, 0x5C6, 0x476, 0x776, 0x68E, 0x62E, 0x6E8, 0x6E2, 0x6EE, 0x758, 0x746, 0x716, 0x768, 0x762, 0x71A, 0x77A, 0x642, 0x78A, 0x530, 0x50C, 0x4B0, 0x486, 0x42C, 0x426, 0x590, 0x584, 0x4D0, 0x4C2, 0x434, 0x432, 0x612, 0x650, 0x7BA, 0x614, 0x47A, 0x53C, 0x4BC, 0x49E, 0x5E4, 0x4F4, 0x4F2, 0x7A4, 0x794, 0x792, 0x6DE, 0x6F6, 0x7B6, 0x578, 0x51E, 0x45E, 0x5E8, 0x5E2, 0x7A8, 0x7A2, 0x5DE, 0x5EE, 0x75E, 0x7AE}; + +constexpr uint16_t startPattern = 0x690; +constexpr uint16_t stopPattern = 0x18EB; + +Code128BView::Code128BView() : + View(), + m_moduleWidth(0), + m_data(nullptr) +{ +} + +void Code128BView::setData(const char * data) { + m_data = data; + markRectAsDirty(bounds()); +} + +void Code128BView::layoutSubviews() { + updateModuleWidth(); +} + +void Code128BView::updateModuleWidth() { + if (m_data == nullptr) { + m_moduleWidth = 0; + return; + } + + int numberOfModules = + 10 + // quiet zone + 11 + // start + 11 * strlen(m_data) + // data + 11 + // checksum + 13; // stop + + m_moduleWidth = bounds().width() / numberOfModules; +} + +void Code128BView::drawQuietZoneAt(KDContext * ctx, KDCoordinate * x) const { + ctx->fillRect(KDRect(*x, 0, 10*m_moduleWidth, bounds().height()), KDColorWhite); + *x = *x + 10*m_moduleWidth; +} + +void Code128BView::drawPatternAt(KDContext * ctx, uint16_t pattern, KDCoordinate * x, KDCoordinate width) const { + assert(width <= 16); + for (int i=0; ifillRect(KDRect(*x, 0, m_moduleWidth, bounds().height()), KDColorBlack); + } + *x = *x + m_moduleWidth; + } +} + +void Code128BView::drawCharAt(KDContext * ctx, char c, KDCoordinate * x) const { + return drawPatternAt(ctx, patterns[c-32], x); +} + +int Code128BView::checksum() const { + int checksum = 104; + const char * letter = m_data; + int i = 1; + while (*letter != 0) { + checksum += (*letter - 32)*i; + i++; + letter++; + } + return checksum % 103; +} + +// Serial Number is 96 bits = 4 * 24 bits = 4 * 4 letters in Base64 = 16 letters + +void Code128BView::drawRect(KDContext * ctx, KDRect rect) const { + if (m_moduleWidth == 0) { + // Not enough space for given string + ctx->fillRect(rect, KDColorRed); + return; + } + + ctx->fillRect(rect, KDColorWhite); + + KDCoordinate x = 0; + drawQuietZoneAt(ctx, &x); + drawPatternAt(ctx, startPattern, &x); + const char * letter = m_data; + while (*letter != 0) { + drawCharAt(ctx, *letter, &x); + letter++; + } + drawPatternAt(ctx, patterns[checksum()], &x); + drawPatternAt(ctx, stopPattern, &x, 13); + drawQuietZoneAt(ctx, &x); + + ctx->drawString(m_data, KDPointZero); +} + +} + diff --git a/apps/hardware_test/code_128b_view.h b/apps/hardware_test/code_128b_view.h new file mode 100644 index 000000000..84f1ecd5f --- /dev/null +++ b/apps/hardware_test/code_128b_view.h @@ -0,0 +1,28 @@ +#ifndef HARDWARE_TEST_CODE_128B_VIEW_H +#define HARDWARE_TEST_CODE_128B_VIEW_H + +#include + +namespace HardwareTest { + +class Code128BView : public View { +public: + Code128BView(); + void drawRect(KDContext * ctx, KDRect rect) const override; + void setData(const char * data); + void layoutSubviews() override; +private: + static constexpr KDCoordinate charPatternWidth = 11; + void updateModuleWidth(); + int checksum() const; + void drawQuietZoneAt(KDContext * ctx, KDCoordinate * x) const; + void drawPatternAt(KDContext * ctx, uint16_t pattern, KDCoordinate * x, KDCoordinate width = charPatternWidth) const; + void drawCharAt(KDContext * ctx, char c, KDCoordinate * x) const; + int m_moduleWidth; + const char * m_data; +}; + +} + +#endif + diff --git a/apps/hardware_test/keyboard_test_controller.cpp b/apps/hardware_test/keyboard_test_controller.cpp index f73e353c0..f7246873c 100644 --- a/apps/hardware_test/keyboard_test_controller.cpp +++ b/apps/hardware_test/keyboard_test_controller.cpp @@ -10,8 +10,7 @@ namespace HardwareTest { KeyboardTestController::KeyboardTestController(Responder * parentResponder) : ViewController(parentResponder), - m_keyboardView(), - m_screenTestController(nullptr) + m_keyboardView() { } @@ -25,8 +24,8 @@ bool KeyboardTestController::handleEvent(Ion::Events::Event event) { if (state == onlyKeyDown) { m_keyboardView.setTestedKeyIndex(m_keyboardView.testedKeyIndex()+1); if (m_keyboardView.testedKeyIndex() == Ion::Keyboard::NumberOfValidKeys) { - ModalViewController * modal = (ModalViewController *)parentResponder(); - modal->displayModalViewController(&m_screenTestController, 0.0f, 0.0f); + // Returning false will go to the next step in the WizardViewController + return false; } } return true; diff --git a/apps/hardware_test/keyboard_test_controller.h b/apps/hardware_test/keyboard_test_controller.h index 28c84f853..7062d66c1 100644 --- a/apps/hardware_test/keyboard_test_controller.h +++ b/apps/hardware_test/keyboard_test_controller.h @@ -3,7 +3,6 @@ #include #include "keyboard_view.h" -#include "screen_test_controller.h" namespace HardwareTest { @@ -15,7 +14,6 @@ public: void viewWillAppear() override; private: KeyboardView m_keyboardView; - ScreenTestController m_screenTestController; }; } diff --git a/apps/hardware_test/led_test_controller.cpp b/apps/hardware_test/led_test_controller.cpp index 7edd63053..74c1ad3d4 100644 --- a/apps/hardware_test/led_test_controller.cpp +++ b/apps/hardware_test/led_test_controller.cpp @@ -10,8 +10,7 @@ constexpr KDColor LEDTestController::k_LEDColors[k_numberOfColors]; LEDTestController::LEDTestController(Responder * parentResponder) : ViewController(parentResponder), m_view(), - m_LEDColorIndex(0), - m_batteryTestController(this) + m_LEDColorIndex(0) { } @@ -23,8 +22,8 @@ bool LEDTestController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK) { setLEDColor(LEDColorAtIndex(m_LEDColorIndex++)); if (m_LEDColorIndex == k_numberOfColors) { - ModalViewController * modal = (ModalViewController *)parentResponder(); - modal->displayModalViewController(&m_batteryTestController, 0.0f, 0.0f); + // Next step, see WizardViewController + return false; } } return true; diff --git a/apps/hardware_test/led_test_controller.h b/apps/hardware_test/led_test_controller.h index dbe686fe1..92d74ed0b 100644 --- a/apps/hardware_test/led_test_controller.h +++ b/apps/hardware_test/led_test_controller.h @@ -2,7 +2,6 @@ #define HARDWARE_TEST_LED_TEST_CONTROLLER_H #include -#include "battery_test_controller.h" #include "arrow_view.h" namespace HardwareTest { @@ -37,7 +36,6 @@ private: static KDColor LEDColorAtIndex(int i); ContentView m_view; int m_LEDColorIndex; - BatteryTestController m_batteryTestController; }; } diff --git a/apps/hardware_test/screen_test_controller.cpp b/apps/hardware_test/screen_test_controller.cpp index 4eb2867d1..e9a86584e 100644 --- a/apps/hardware_test/screen_test_controller.cpp +++ b/apps/hardware_test/screen_test_controller.cpp @@ -8,8 +8,7 @@ namespace HardwareTest { ScreenTestController::ScreenTestController(Responder * parentResponder) : ViewController(parentResponder), m_patternIndex(0), - m_view(), - m_ledTestController(this) + m_view() { } @@ -22,8 +21,8 @@ bool ScreenTestController::handleEvent(Ion::Events::Event event) { return true; } if (m_patternIndex == Pattern::numberOfPatterns()) { - ModalViewController * modal = (ModalViewController *)parentResponder(); - modal->displayModalViewController(&m_ledTestController, 0.0f, 0.0f); + // Go to the next step - this will be handled by the WizardViewController + return false; } else { showNextPattern(); } diff --git a/apps/hardware_test/screen_test_controller.h b/apps/hardware_test/screen_test_controller.h index d73a14f90..2b9570872 100644 --- a/apps/hardware_test/screen_test_controller.h +++ b/apps/hardware_test/screen_test_controller.h @@ -2,7 +2,6 @@ #define HARDWARE_TEST_SCREEN_TEST_CONTROLLER_H #include -#include "led_test_controller.h" #include "pattern_view.h" #include "pattern.h" @@ -18,7 +17,6 @@ private: void showNextPattern(); int m_patternIndex; PatternView m_view; - LEDTestController m_ledTestController; }; } diff --git a/apps/hardware_test/serial_number_controller.cpp b/apps/hardware_test/serial_number_controller.cpp new file mode 100644 index 000000000..42671fffb --- /dev/null +++ b/apps/hardware_test/serial_number_controller.cpp @@ -0,0 +1,25 @@ +#include "serial_number_controller.h" +#include + +namespace HardwareTest { + +SerialNumberController::SerialNumberController(Responder * parentResponder) : + ViewController(parentResponder), + m_barCodeView() +{ +} + +void SerialNumberController::viewWillAppear() { + static char serialNumber[24]; + Ion::getSerialNumber(serialNumber); + m_barCodeView.setData(serialNumber); +} + +bool SerialNumberController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OnOff || event == Ion::Events::OK) { + return false; + } + return true; +} + +} diff --git a/apps/hardware_test/serial_number_controller.h b/apps/hardware_test/serial_number_controller.h new file mode 100644 index 000000000..8adee0ec4 --- /dev/null +++ b/apps/hardware_test/serial_number_controller.h @@ -0,0 +1,22 @@ +#ifndef HARDWARE_TEST_SERIAL_NUMBER_CONTROLLER_H +#define HARDWARE_TEST_SERIAL_NUMBER_CONTROLLER_H + +#include +#include "code_128b_view.h" + +namespace HardwareTest { + +class SerialNumberController : public ViewController { +public: + SerialNumberController(Responder * parentResponder); + View * view() override { return &m_barCodeView; } + bool handleEvent(Ion::Events::Event event) override; + void viewWillAppear() override; +private: + Code128BView m_barCodeView; +}; + +} + +#endif + diff --git a/apps/hardware_test/usb_test_controller.cpp b/apps/hardware_test/usb_test_controller.cpp index 56d4fc017..16dd459ce 100644 --- a/apps/hardware_test/usb_test_controller.cpp +++ b/apps/hardware_test/usb_test_controller.cpp @@ -10,10 +10,8 @@ namespace HardwareTest { USBTestController::USBTestController(Responder * parentResponder) : ViewController(parentResponder), - Timer(1), m_view(), - m_shouldPlugUSB(true), - m_resetController(this) + m_shouldPlugUSB(true) { } @@ -22,10 +20,6 @@ View * USBTestController::view() { } bool USBTestController::handleEvent(Ion::Events::Event e) { - return true; -} - -bool USBTestController::fire() { if (Ion::USB::isPlugged() && m_shouldPlugUSB) { m_view.USBTextView()->setText(k_USBUnplugText); m_view.arrowView()->setDirection(false); @@ -34,11 +28,10 @@ bool USBTestController::fire() { return true; } if (!Ion::USB::isPlugged() && !m_shouldPlugUSB) { - ModalViewController * modal = (ModalViewController *)parentResponder(); - modal->displayModalViewController(&m_resetController, 0.0f, 0.0f); - return true; + // We're done, tell WizardViewController to go to the next step + return false; } - return false; + return true; } void USBTestController::viewWillAppear() { diff --git a/apps/hardware_test/usb_test_controller.h b/apps/hardware_test/usb_test_controller.h index 7b111d61b..228641ceb 100644 --- a/apps/hardware_test/usb_test_controller.h +++ b/apps/hardware_test/usb_test_controller.h @@ -2,19 +2,18 @@ #define HARDWARE_TEST_USB_TEST_CONTROLLER_H #include -#include "reset_controller.h" #include "arrow_view.h" namespace HardwareTest { -class USBTestController : public ViewController, public Timer { +class USBTestController : public ViewController { public: USBTestController(Responder * parentResponder); View * view() override; void viewWillAppear() override; bool handleEvent(Ion::Events::Event e) override; private: - bool fire() override; + //bool fire() override; class ContentView : public SolidColorView { public: ContentView(); @@ -40,7 +39,6 @@ private: constexpr static const char * k_USBUnplugText = "OK, UNPLUG USB"; ContentView m_view; bool m_shouldPlugUSB; - ResetController m_resetController; }; }