diff options
-rw-r--r-- | HISTORY | 5 | ||||
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | lib/README | 3 | ||||
-rw-r--r-- | lib/vdr/osd/item.rb | 48 | ||||
-rw-r--r-- | lib/vdr/osd/menu.rb | 119 | ||||
-rw-r--r-- | lib/vdr/osd/osdmessage.rb | 2 | ||||
-rw-r--r-- | lib/vdr/osd/textview.rb | 2 | ||||
-rw-r--r-- | spec/vdr/osd/menu_spec.rb | 50 | ||||
-rw-r--r-- | spec/vdrswig-fakewrapper.rb | 21 | ||||
-rw-r--r-- | swig/cOsdItem.i | 1 | ||||
-rw-r--r-- | swig/cOsdMenu.i | 10 |
11 files changed, 249 insertions, 26 deletions
@@ -1,3 +1,8 @@ +2009-xx-xx: Version x.x.x + +- Added RDoc documentation (Closes: #90) +- Added on_keypress event to menu (Closes: #96) + 2009-02-14: Version 0.0.1 - Initial proof-of-concept release @@ -73,6 +73,11 @@ OBJS := $(addsuffix .o,$(basename ${SRCS})) OBJS += $(addsuffix _wrap.o,$(basename ${INTERFACES})) +### RDoc + +RDOC ?= /usr/bin/rdoc +RDOC_INPUT := $(shell find lib -name "*") + ### Implicit rules: .PRECIOUS: %_wrap.cc @@ -125,7 +130,7 @@ i18n: $(I18Nmsgs) ### Targets: -all: libvdr-$(PLUGIN).so i18n +all: libvdr-$(PLUGIN).so i18n rdoc test: spec -c -fs . @@ -134,6 +139,12 @@ libvdr-$(PLUGIN).so: $(OBJS) $(CXX) $(CXXFLAGS) -shared $(OBJS) -L. $(LIBS) -o $@ @cp $@ $(LIBDIR)/$@.$(APIVERSION) +.rdoc: $(RDOC_INPUT) + $(RDOC) --main lib/README -S -U lib/README -o rdoc $< + @touch .rdoc + +rdoc: .rdoc + dist: test clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @@ -147,4 +158,5 @@ dist: test clean clean: @-rm -f $(BUILD_DEPFILE) *.so* *.tar.gz core* *~ @-rm -f swig/*_wrap.* swigrubyrun.h + @-rm -rf rdoc .rdoc @-find . -name \*.\o -exec rm -f {} \; diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..43be820 --- /dev/null +++ b/lib/README @@ -0,0 +1,3 @@ +Here goes some gerneral notes and get-going examples for the Ruby API... + +TODO diff --git a/lib/vdr/osd/item.rb b/lib/vdr/osd/item.rb index 4c78040..ce4a18a 100644 --- a/lib/vdr/osd/item.rb +++ b/lib/vdr/osd/item.rb @@ -20,20 +20,60 @@ module Vdr module Osd + # + # An #Item represents an entry in an OSD #Menu. + # Each item has a #text that will be shown on the menu and a + # #context which can be used to store any kind of object + # associated with this menu item. + # + # == Example + # + # new_menu = Menu.new('A simple menu') do |menu| + # menu.add_item(Item.new('First Item').on_select { puts 'Item 1 selected' }) + # new_item = Item.new('Second Item') do |item| + # item.context = { :first_name => 'James Tiberius', :last_name => 'Kirk' } + # item.on_select do |selected_item| + # name = selected_item.context + # puts "Selected #{name[:last_name]}, #{name[:first_name]}" + # end + # end + # menu.add_item(new_item) + # end + # class Item < Vdr::Swig::COsdItem + + # The text of the item which will be shown on its parent #Menu attr_reader :text + + # A free assignable context associated with an #Item attr_accessor :context - def initialize(text = nil) + # + # Creates a new item. If _text_ is given, it will become the text displayed on the + # parent menu for this item. + # + # Item.new('my item') #=> Creates a new item shown with 'my item' + # Item.new {|i| i.title = 'another item'} #=> Creates a new item and sets its title to 'another item' + # + def initialize(text = nil) # :yields: item @text = text super(text) + yield self if block_given? + end + + # Change the item text + def text=(text) + @text = text + set_text(text) end - def on_select(&block) - @select = block + # The block assigned to on_select will be executed, when + # the item is selected from the menu + def on_select(&block) # :yields: item + @select = block end - def process_key(key) + def process_key(key) # :nodoc: state = super(key) if key == Vdr::Swig::KOk if @select diff --git a/lib/vdr/osd/menu.rb b/lib/vdr/osd/menu.rb index 5284726..f266923 100644 --- a/lib/vdr/osd/menu.rb +++ b/lib/vdr/osd/menu.rb @@ -20,57 +20,152 @@ module Vdr module Osd + # + # The Menu class represents a basic OSD menu with a title + # and a bunch of items. + # class Menu < Vdr::Swig::COsdMenu + # The title of the menu attr_reader :title - def initialize(title=nil) + + # Creates a new menu, optionally with the given _title_ + def initialize(title=nil) # :yields: menu @title = title super(@title) @items = [] + @red_help = @green_help = @yellow_help = @blue_help = nil + @keypress_event_handler = {} yield(self) if block_given? end + # Sets the _title_ of the menu def title=(title) @title = title set_title(@title) end + # Adds the Item _item_ to the menu def add_item(item) @items << item add(item) end + # Item reference returning an Item by index def [](index) return @items[index] end + # Opens the given _menu_ as a sub menu def open_sub_menu(menu) add_sub_menu(menu) end - def process_key(key) - state = super(key) - case @close_request - when :close - return Vdr::Swig::OsBack - when :close_all - return Vdr::Swig::OsEnd - end - return state - end - + # Request to close the menu def close @close_request = :close end + # Request to close all menus def close_all @close_request = :close_all end + # Create and add a new item with the given _title_ and returns the added + # Item def add_new_item(title) item = Item.new(title) add_item(item) return item end + + # Sets the help text for the red button + def red_help=(text) + @red_help = text + update_help_texts + end + + # Sets the help text for the green button + def green_help=(text) + @green_help = text + update_help_texts + end + + # Sets the help text for the yellow button + def yellow_help=(text) + @yellow_help = text + update_help_texts + end + + # Sets the help text for the blue button + def blue_help=(text) + @blue_help = text + update_help_texts + end + + # + # Sets an event handler for the key press event. If _key_ is not + # given, the event handler will be called for any key, otherwise + # just for the specific key. In the latter case, no parameter is + # passed to the event handler. + # + # menu.on_keypress do |key| + # case key + # when :key_red + # puts "Red key pressed" + # when :key_yellow + # puts "Yellow key pressed" + # end + # end + # + # menu.on_keypress(:key_red) { puts 'Red key pressed' } + # + def on_keypress(key=:key_any, &event_handler) # :yield: key + @keypress_event_handler[key] = event_handler + end + + # Deletes all menu items + def clear + super + end + + # Refresh the menu. This must be called, when the menu has been changed. + def refresh + display + end + + protected + + def process_key(key) # :nodoc: + state = super(key) + case @close_request + when :close + return Vdr::Swig::OsBack + when :close_all + return Vdr::Swig::OsEnd + end + key_symbol = KEYMAP[key] + if @keypress_event_handler[:key_any] + @keypress_event_handler[:key_any].call(key_symbol) + end + if @keypress_event_handler[key_symbol] + @keypress_event_handler[key_symbol].call + end + return state + end + + private + + KEYMAP = + { + Vdr::Swig::KRed => :key_red, + Vdr::Swig::KGreen => :key_green, + Vdr::Swig::KYellow => :key_yellow, + Vdr::Swig::KBlue => :key_blue, + } + + def update_help_texts + set_help(@red_help, @green_help, @yellow_help, @blue_help) + end end end end diff --git a/lib/vdr/osd/osdmessage.rb b/lib/vdr/osd/osdmessage.rb index c6cfe8d..fe2401c 100644 --- a/lib/vdr/osd/osdmessage.rb +++ b/lib/vdr/osd/osdmessage.rb @@ -20,7 +20,9 @@ module Vdr module Osd + # Provides an interface to display simple one line OSD messages class OsdMessage + # Display _message_ for then given number of _seconds_ def OsdMessage.Show(message, seconds=5) Vdr::Swig::COsdMessage.confirm(message, seconds, false) end diff --git a/lib/vdr/osd/textview.rb b/lib/vdr/osd/textview.rb index 87bce65..d1fafbc 100644 --- a/lib/vdr/osd/textview.rb +++ b/lib/vdr/osd/textview.rb @@ -20,7 +20,9 @@ module Vdr module Osd + # A TextView displays a vertical scrollable text in the OSD class TextView < Vdr::Swig::CMenuText + # Creates a new text view with the given _title_ and _text_ def initialize(title, text) super(title, text) end diff --git a/spec/vdr/osd/menu_spec.rb b/spec/vdr/osd/menu_spec.rb index dff9b31..21235b9 100644 --- a/spec/vdr/osd/menu_spec.rb +++ b/spec/vdr/osd/menu_spec.rb @@ -68,21 +68,65 @@ describe Vdr::Osd::Menu do end it 'should return the parents result from process_key' do - @menu.process_key(Vdr::Swig::KOk).should == Vdr::Swig::OsUnknown + @menu.fake_process_key(Vdr::Swig::KOk).should == Vdr::Swig::OsUnknown end it 'should return OsBack from process_key when requesting to close the menu' do @menu.close - @menu.process_key(Vdr::Swig::KOk).should == Vdr::Swig::OsBack + @menu.fake_process_key(Vdr::Swig::KOk).should == Vdr::Swig::OsBack end it 'should return OsEnd from process_key when requesting to close all menus' do @menu.close_all - @menu.process_key(Vdr::Swig::KOk).should == Vdr::Swig::OsEnd + @menu.fake_process_key(Vdr::Swig::KOk).should == Vdr::Swig::OsEnd end it 'should add a new menu item' do @menu.add_new_item('item') @menu[0].text.should == 'item' end + + it 'should set the color help texts' do + @menu.red_help = 'Red' + @menu.COsdMenu_help_texts.should == ['Red', nil, nil, nil] + + @menu.green_help = 'Green' + @menu.COsdMenu_help_texts.should == ['Red', 'Green', nil, nil] + + @menu.yellow_help = 'Yellow' + @menu.COsdMenu_help_texts.should == ['Red', 'Green', 'Yellow', nil] + + @menu.blue_help = 'Blue' + @menu.COsdMenu_help_texts.should == ['Red', 'Green', 'Yellow', 'Blue'] + end + + it 'should trigger the on_keypress event when a key is pressed' do + pressed_key = nil + @menu.on_keypress do |key| + pressed_key = key + end + @menu.fake_process_key(Vdr::Swig::KRed) + pressed_key.should == :key_red + end + + it 'should trigger the on_keypress event when a specific key is pressed' do + red_key_pressed = false + @menu.on_keypress(:key_red) do + red_key_pressed = true + end + @menu.fake_process_key(Vdr::Swig::KGreen) + red_key_pressed.should == false + @menu.fake_process_key(Vdr::Swig::KRed) + red_key_pressed.should == true + end + + it 'should clear the menu' do + @menu.clear + @menu.COsdMenu_cleared.should == true + end + + it 'should redisplay the menu when refreshing' do + @menu.should_receive(:display) + @menu.refresh + end end diff --git a/spec/vdrswig-fakewrapper.rb b/spec/vdrswig-fakewrapper.rb index a004ac3..2b98723 100644 --- a/spec/vdrswig-fakewrapper.rb +++ b/spec/vdrswig-fakewrapper.rb @@ -27,8 +27,13 @@ module Vdr OsEnd = :OsEnd KOk = 1 + KRed = 2 + KGreen = 3 + KBlue = 4 + KYellow = 5 + class COsdMenu - attr_reader :cosdmenu_ctor_arguments, :current + attr_reader :cosdmenu_ctor_arguments, :current, :COsdMenu_help_texts, :COsdMenu_cleared def initialize(*args) @cosdmenu_ctor_arguments = args @@ -39,15 +44,27 @@ module Vdr def add(item) end - + def process_key(key) return OsUnknown end + + def fake_process_key(key) + return process_key(key) + end def simulate_select(index) @current = index process_key(Vdr::Swig::KOk) end + + def set_help(red, green, yellow, blue) + @COsdMenu_help_texts = [red, green, yellow, blue] + end + + def clear + @COsdMenu_cleared = true + end end class COsdItem diff --git a/swig/cOsdItem.i b/swig/cOsdItem.i index c50181c..790bbaa 100644 --- a/swig/cOsdItem.i +++ b/swig/cOsdItem.i @@ -33,4 +33,5 @@ class cOsdItem virtual ~cOsdItem(); cOsdItem(const char *Text, eOSState State = osUnknown, bool Selectable = true); virtual eOSState ProcessKey(eKeys Key); + void SetText(const char *Text); }; diff --git a/swig/cOsdMenu.i b/swig/cOsdMenu.i index ecc4678..765565a 100644 --- a/swig/cOsdMenu.i +++ b/swig/cOsdMenu.i @@ -44,12 +44,14 @@ class cOsdMenu { protected: eOSState AddSubMenu(cOsdMenu *SubMenu); + virtual eOSState ProcessKey(eKeys Key); + void SetHelp(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL); + void Add(cOsdItem *Item, bool Current = false, cOsdItem *After = NULL); + void SetTitle(const char *Title); + virtual void Clear(); + virtual void Display(void); public: cOsdMenu(const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0); virtual ~cOsdMenu(); - int Current(void) const; - void Add(cOsdItem *Item, bool Current = false, cOsdItem *After = NULL); - void Ins(cOsdItem *Item, bool Current = false, cOsdItem *Before = NULL); - virtual eOSState ProcessKey(eKeys Key); }; |