Source code for the Curilights Controller. See http://www.saccade.com/writing/projects/CuriController/ for details.
Dependencies: FatFileSystem mbed
This is the source code for the Curilights controller. This lets you interactively control a string of Curilights. It provides a simple click-wheel user interface for changing colors, brightness and behavior. It responds to movement and lighting.
Finished Controller
System Block Diagram
UIMenu.cpp
- Committer:
- isonno
- Date:
- 2012-01-16
- Revision:
- 2:965388eecf95
- Parent:
- 1:d1da77023e6a
- Child:
- 3:0ac64c4ca40f
File content as of revision 2:965388eecf95:
// // UIMenu - Click-knob menu implementation // #include "NokiaLCD.h" #include "UIMenu.h" #include "HoldInterrupts.h" static Timeout gScreenTimer; void PushKnobUI::ConnectDevices( RotaryEncoder * knob, PushButton * button ) { HoldInterrupts holdint(); if (! knob && fKnob) // Disconnect { fKnob->detach(); fKnob = NULL; } if (! button && fKnobButton) { fKnobButton->detach(); fKnobButton = NULL; } if (knob && !fKnob) { fKnob = knob; //fKnob->attach( this, &UIMenu::KnobMoved ); AttachKnob( fKnob ); } if (button && !fKnobButton) { fKnobButton = button; //fKnobButton->attach( this, &UIMenu::KnobPushed ); AttachButton( fKnobButton ); } } void PushKnobUI::SwitchControl( PushKnobUI * other ) { other->ConnectDevices( fKnob, fKnobButton ); fKnob = NULL; fKnobButton = NULL; } int32_t PushKnobUI::KnobMoved( int32_t step ) { printf("Knob moved %d\r\n", step ); Wake(); return step; } void PushKnobUI::KnobPushed() { Wake(); printf("Button pushed\r\n"); } void PushKnobUI::Wake() { fLCD->fade_backlight( true ); gScreenTimer.detach(); gScreenTimer.attach( this, &PushKnobUI::Sleep, 10 ); } void PushKnobUI::Sleep() { fLCD->fade_backlight( false ); gScreenTimer.detach(); } //---------------------------------------------------- UIMenu::UIMenu( CheapLCD * lcd, const char * header, bool upMenuItem ) : PushKnobUI( lcd ), fHeader( header ), fDisplayOn( false ), fUpMenuItem( upMenuItem ), fSelectedItem( kNoSelection ), fLCD( lcd ) {} void UIMenu::AddItem( const char * label ) { fLabels.push_back( string( label )); if (fDisplayOn) Display( true ); // Refresh } void UIMenu::ChangeItem( int item, const char * label ) { if ((item > 0) && (item < fLabels.size())) { fLabels[item] = string( label ); DrawItem( item ); } } int32_t UIMenu::KnobMoved( int32_t step ) { Wake(); if (fSelectedItem == kNoSelection) { fSelectedItem = (step > 0) ? 0 : fLabels.size() - 1; DrawItem( fSelectedItem ); } else { int lastItem = fSelectedItem; fSelectedItem += step; // Handle wrap-around if (fSelectedItem < 0) fSelectedItem = fLabels.size() - 1; if (fSelectedItem == fLabels.size()) fSelectedItem = 0; DrawItem( lastItem ); DrawItem( fSelectedItem ); } return 0; } void UIMenu::KnobPushed() { Wake(); printf("Selected %s\n\r", fLabels[fSelectedItem].c_str() ); } void UIMenu::SwitchTo( UIMenu * nextMenu ) { Display( false ); SwitchControl( nextMenu ); nextMenu->Display( true ); } // Parameters controlling the display layout const int kLineSpace = 20; const int kTopGap = 4; const int kIndent = 12; #define MEDGREEN 0x0A0 // "medium" green void UIMenu::DrawItem( int i ) { if (! fDisplayOn) return; uint32_t foreColor = WHITE; uint32_t backColor = (i == fSelectedItem) ? MEDGREEN : BLACK; fLCD->clear( backColor, 0, i * kLineSpace + kLineSpace + kTopGap, 131, (i+1) * kLineSpace + kLineSpace + kTopGap ); fLCD->draw_glyph_text( foreColor, backColor, kIndent, (i+2) * kLineSpace, fLabels[i].c_str() ); } void UIMenu::Display( bool on ) { if (on) { fDisplayOn = true; fLCD->clear( BLACK, 0, 0, 131, kLineSpace + kTopGap ); fLCD->clear( GRAY, 0, kLineSpace + kTopGap-1, 131, kLineSpace + kTopGap ); if (! fHeader.empty()) fLCD->draw_glyph_text( WHITE, BLACK, 2, kLineSpace-2, fHeader.c_str() ); int maxLines = std::min( (int)((131 - (kLineSpace + kTopGap)) / kLineSpace), (int)fLabels.size() ); for (int i = 0; i < maxLines; ++i) DrawItem( i ); } else fDisplayOn = false; }