Questions on writing my first plugin

Discussion in 'Plugin Development' started by huha, March 20, 2012.

  1. huha
    • Premium Supporter

    huha Extension Developer

    Joined:
    January 3, 2008
    Messages:
    890
    Likes Received:
    550
    Gender:
    Male
    Ratings:
    +622 / 0
    Home Country:
    Germany Germany
    Show System Specs
    Update: The language files are not working for the summer release



    I started to write my first plugin and got excited about MP2.

    As I had no idea about xaml or MP2 before, I am documenting some steps in learning which may be helpful for others, too.

    The following steps describe some basic examples for MP2 and give simple code examples.
    The plugin has no real meaning besides demonstrating and testing basic functions in MP2

    Before you continue you should have understood the function of the "Hallo World Plugin".
    Don´t get frustrated if you did not understand the WIKI MP2 documentation. Many things became more clear after i was going through the following steps.


    **************************************************************
    Step1: (Closed, source code attached)
    **************************************************************
    -the plugin MyTestPlugin has a dependency on the Configuration Manager Plugin in plugin.xml

    -example for a push navigation button from the MyTestPlugin to the HelloWorldplugin in workflow\MyTestPlugin.xml

    -example for a push navigation button from the HelloWorldplugin to the MyTestPlugin in workflow\MyTestPlugin.xml

    -example for a function button FunctionButton in workflow\MyTestPlugin.xml

    -example for generating a "push" workflow transition (from the MyTestPlugin to the HelloWorldplugin) in the model code triggered by the Push button

    -example for generating a "pop" workflow transition (from the MyTestPlugin to the previous screen) in the model code triggered by the Pop button

    -example for a button "Press me" toggling a label in the skin

    -example for tracing the workflow states using the IWorkFlowModel functions

    -example for logging

    -cleanup on naming convention


    **************************************************************
    Step2: (closed, source attached)
    **************************************************************
    - cleanup on naming convention

    - adding config settings to the plugin (string, integer, bool) in the configuration folder. Loadsettings example in the model MyTestPlugin.cs.

    - example for messaging when a configuration setting did change(send in the configuration if a string changes its value and receive in the model MyTestPlugin.cs)

    - assigning keys/ IR commands to functions in the skin MyTestPlugin.xaml
    pressing F1 button (or whatever you configured for MyButton_Key in the configuration) will call the function ChangeHelloWorldString.

    - assigning keys/ IR commands to functions in the model MyTestPlugin.cs (Pause key) using the IInputManager which will call the function MyFunctionButton in the model MyTestPlugin.cs


    **************************************************************
    Step3: (closed, source attached)
    **************************************************************
    - adding another child skin (MyTestPluginScreen2.xaml and its model MyTestPluginScreen2.cs)

    - transition from parent to child and revers (new workflow in workflow\MyTestPlugin.xml)

    - listview menu processing (MyTestPluginScreen2.xaml and its model MyTestPluginScreen2.cs)
    (The defaultstyle refers to a key "Name" !) the number of listview menu items is determined by the integer in the configuration settings.

    - creating an information dialog and watch its closing in the model MyTestPlugin.cs

    - creating a dialog menu in the model MyTestPlugin.cs with a derived skin SimpleDialogMenu.xaml

    - creating a input textbox dialog which can use the virtual keyboard in the model MyTestPlugin.cs with a skin SimpleDialogTextBoxInput.xaml


    **************************************************************
    Step4: (closed, source attached)
    **************************************************************
    - Important: You need to change to the MP2 Easter Build version (only working for default skin)
    - Important: You need to have MPExtended to be installed (not working for TV4Home!)

    - the Screen2 now implements a gui dialog where the user is asked to select a tv group. Then all channels of the selected Tv group will be displayed in the listitem on screen2. For this the SlimTvInterface was used with its implemented functions from Morpheus. Just register the global _tvHandler in the constructor and use the _tvhandler functions to get an IList of all groups

    _tvHandler.ChannelAndGroupInfo.GetChannelGroups(out mygroups)
    SimpleMenuDialogScreen2() implements a menu dialog, where the user can select the tv group derived from the dialog in Step3.

    -The channel names are obtained in a similar way in InitListItems(). They are displayed as listitems in the skin.
    In a similar way schedules and programs can be handled. Look at the SlimTvInterfaces from morpheus_xx

    - As there was no definition for TV database settings in SlimTvInterfaces i have created an own class derived from the SlimTvMPExtended class to connect to the Tvserver and read/write data base settings. That´s why step4 needs MPExtended only.
    In MyTestPluginMPExtendedProvider.cs the functions

    GetConnectedServers(out List<ServerName> serverNames)
    ReadSetting(int serverId, string tagName, string defaultValue, out Setting setting)
    WriteSetting(int serverId, string tagName, string value)

    have been defined in addition to reusing the functions for connecting to the Tvserver from the original code of morpheus_xx. This may become void in the future if morpheus_xx implements the settings in SlimTvInterfaces. As MPExtended supports multiple tv servers the function GetConnectedServers lists all defined and connected tv servers.

    -The testplugin uses this class in the main screen and reads a tvserver database setting within the function OnPageLoad and displays the setting "postRecordInterval" whenever the main screen is entered.
    The menu dialog is used to select different numbers and write back this setting with the selected value to the tv server database in the function MenuItemSelected(ListItem myitem).

    **************************************************************
    Step5: (closed, source attached)
    **************************************************************
    Step 5 gives an example for a process plugin, which will open a dialog box if the workflow changes. It consists of the derived classes
    BaseMessageControlledModel, IPluginStateTracker
    In contrast to a workflowmodel it will be activated at the beginning and is ideal for implementing a process plugin. This plugin just listens for new messages and opens a dialog box if a new message has been received. Trace the log file to see the actual states from the PluginStateTracker. Check the plugin.xml file to see how the plugin is registered.


    I have posted the updated code in the zip file.

    Update 6/17/2012:
    - updated all the source code and removed a few minor bugs
    - removed dependency on TV plugin, as it caused an issue for other skins
     

    Attached Files:

    • Step1.jpg
      Step1.jpg
      File size:
      141 KB
      Uploaded:
      March 25, 2012
      Views:
      248
    • Step2.jpg
      Step2.jpg
      File size:
      155.6 KB
      Uploaded:
      March 25, 2012
      Views:
      211
    • Step3.jpg
      Step3.jpg
      File size:
      252.6 KB
      Uploaded:
      April 8, 2012
      Views:
      191
    • Step4.JPG
      Step4.JPG
      File size:
      68 KB
      Uploaded:
      April 15, 2012
      Views:
      175
    • MP2 MyTestPlugin.zip
      File size:
      6.2 MB
      Uploaded:
      June 17, 2012
      Views:
      141
    Last edited: July 25, 2012
    • Like Like x 3
  2. Google AdSense Guest Advertisement



    to hide all adverts.
  3. morpheus_xx
    • Team MediaPortal

    morpheus_xx Lead Dev MP2

    Joined:
    March 24, 2007
    Messages:
    10,953
    Likes Received:
    4,719
    Ratings:
    +6,759 / 11
    Home Country:
    Germany Germany
    Show System Specs
    I've checked your plugin. The text is not updated after button click, because you are missing a Property.

    If you add
    Code (Text):
    1.   public AbstractProperty FunctionButtonLabelProperty
    2.     {
    3.         get { return _functionButtonProperty; }
    4.     }
    to code it works.

    Background is the databinding: FunctionButtonLabel exposes the string, the skin engine's databinding always tries to attach to FunctionButtonLabelProperty, so that it is able to react on property change events.

    If you want to make debugging easier, add this commands to the project "post build actions":
    Code (Text):
    1. xcopy /Y "$(ProjectDir)plugin.xml" "$(SolutionDir)..\Bin\$(SolutionName)\$(OutDir)Plugins\$(ProjectName)\"
    2. mkdir "$(SolutionDir)..\Bin\$(SolutionName)\$(OutDir)Plugins\$(ProjectName)\Language"
    3. robocopy "$(ProjectDir)Language" "$(SolutionDir)..\Bin\$(SolutionName)\$(OutDir)Plugins\$(ProjectName)\Language" /MIR /NP
    4. mkdir "$(SolutionDir)..\Bin\$(SolutionName)\$(OutDir)Plugins\$(ProjectName)\Skin"
    5. robocopy "$(ProjectDir)Skin" "$(SolutionDir)..\Bin\$(SolutionName)\$(OutDir)Plugins\$(ProjectName)\Skin" /MIR /NP
    6. xcopy /Y "$(TargetDir)$(ProjectName).dll"  "$(SolutionDir)..\Bin\$(SolutionName)\$(OutDir)Plugins\$(ProjectName)\"
    7.  
    , add the project to the MP2-Client solution.This way the required plugin files are copied to MP2-Client plugins on build.

    Then you can debug directly inside VS2010.
     
    • Like Like x 2
  4. huha
    • Premium Supporter

    huha Extension Developer

    Joined:
    January 3, 2008
    Messages:
    890
    Likes Received:
    550
    Gender:
    Male
    Ratings:
    +622 / 0
    Home Country:
    Germany Germany
    Show System Specs
    morpheus_xx,
    thanks a lot for your help. I defined a property FunctionButtonProperty instead of FunctionButtonLabelProperty.
    I will try your script code. I think I got now a first understanding of the workflowtransitions.
     
  5. huha
    • Premium Supporter

    huha Extension Developer

    Joined:
    January 3, 2008
    Messages:
    890
    Likes Received:
    550
    Gender:
    Male
    Ratings:
    +622 / 0
    Home Country:
    Germany Germany
    Show System Specs
    I found another bug in my example. I did not derive the class from IWorkflowModel, IDisposable
    and i did not specify the workflowmodel in plugin.xml, so the IWorkflowModel implementation did not work.

    I have updated in the first post the plugin with all issues corrected.
     
  6. huha
    • Premium Supporter

    huha Extension Developer

    Joined:
    January 3, 2008
    Messages:
    890
    Likes Received:
    550
    Gender:
    Male
    Ratings:
    +622 / 0
    Home Country:
    Germany Germany
    Show System Specs
    I made some more progress on my first plugin and have documented the steps in my first posting. I got the config settings working and an example for messaging. The later one gave me some headache on transferring a string from a static function to the skin.

    I will be out the next 2 weeks and continue afterwards.

    If someone knows how to attach keys or IR commands to buttons please post.
     
  7. Albert
    • Team MediaPortal

    Albert MP2 Developer

    Joined:
    February 18, 2008
    Messages:
    1,297
    Likes Received:
    1,125
    Gender:
    Male
    Occupation:
    Dipl.-Inform.
    Location:
    Freiburg im Breisgau, Germany
    Ratings:
    +1,130 / 1
    Home Country:
    Germany Germany
    Internally, IR commands are mapped to keys before they are sent through the system.
    To map commands to actions, there are several ways:
    • You can add a key mapping for a screen. To do that, there are two ways:
      • Use the KeyBinding XAML element. That control adds an "invisible" key handler which simply executes a command when the configured key is pressed.
      • Use the KeyBindingControl XAML element.
    • You can add a global key mapping using the SkinEngine's input manager. In method SkinEnginePlugin.RegisterGlobalKeyBindings(), you can see how such global key bindings are used. Please note that global key bindings must be unregistered when your plugin is unloaded, as any other resource which is aquired by a plugin.
     
    • Like Like x 1
  8. huha
    • Premium Supporter

    huha Extension Developer

    Joined:
    January 3, 2008
    Messages:
    890
    Likes Received:
    550
    Gender:
    Male
    Ratings:
    +622 / 0
    Home Country:
    Germany Germany
    Show System Specs
    Albert, thanks for your help here! I got it. I updated Step2 in the first post. I am also making progress on step 3.
    I am starting to understand slowly what great new opportunities MP2 will give for the plugins and skins.
     
  9. Quarter
    • Super User

    Quarter Super User

    Joined:
    June 21, 2010
    Messages:
    722
    Likes Received:
    109
    Gender:
    Male
    Location:
    Queenstown
    Ratings:
    +139 / 2
    Home Country:
    New Zealand New Zealand
    Show System Specs
    Its going to be a very long time (if ever) before I understand mp2 enough to start writing a plugin. I think I will have to stick to mp1. Maybe someone can create a plugin builder to handle all the xmal files. C# I can handle. :(
     
  10. huha
    • Premium Supporter

    huha Extension Developer

    Joined:
    January 3, 2008
    Messages:
    890
    Likes Received:
    550
    Gender:
    Male
    Ratings:
    +622 / 0
    Home Country:
    Germany Germany
    Show System Specs
    After having spent hours without success on the listitem I need to ask for help again:

    I have defined a skin MyTestPluginScreen2.xaml with a listitem in a dockpanel:

    <ListView Name="TestListView" DockPanel.Dock="Center" Height="300" Width="600" ItemsSource="{Binding MyListViewItems}" SelectionChanged="{CommandStencil FocusedItemChanged}"/>

    In the corresponding model MyTestPluginScreen2.cs i have defined:


    private ItemsList _testlist = null;

    public ItemsList MyListViewItems
    {
    get { return _testlist; }
    }




    public void InitListItems()
    {
    //load settings
    MyTestPluginSettings settings = ServiceRegistration.Get<ISettingsManager>().Load<MyTestPluginSettings>();

    //define all items for ListView in skin and use MySetting_Int for number of items to create
    _testlist = new ItemsList();
    for (int i = 0; i < settings.MySetting_Int; i++)
    {
    ListItem myitem = new ListItem();
    string myitemstring = LocalizationHelper.Translate(ITEM_RESOURCE, i);
    myitem.SetLabel("Item",myitemstring);
    mylogger.Debug("Adding item="+myitemstring);
    //this command will be executed after selection
    myitem.Command = new MethodDelegateCommand(() => SelectedItemChanged(i));
    _testlist.Add(myitem);
    }

    //update skin
    MyListViewItems.FireChange();
    }


    I believe i do not have to define any properties, as this is done in the ListItem class.
    I see in the log files that list items are created, but no list item is shown on the screen and i have no idea why.

    I have included the complete code Step3 in a zip file
     

    Attached Files:

    • Step3.zip
      File size:
      1.1 MB
      Uploaded:
      April 7, 2012
      Views:
      209
  11. Albert
    • Team MediaPortal

    Albert MP2 Developer

    Joined:
    February 18, 2008
    Messages:
    1,297
    Likes Received:
    1,125
    Gender:
    Male
    Occupation:
    Dipl.-Inform.
    Location:
    Freiburg im Breisgau, Germany
    Ratings:
    +1,130 / 1
    Home Country:
    Germany Germany
    I think the problem is that you don't define a Style attribute on your ListView, so the default style is used. The default ListView style (DefaultListViewStyle) uses the DefaultItemDataTemplate for presenting the items, which uses the Name label as presentation string. That label is not set by your initialization code...
     
    • Like Like x 1

Users Viewing Thread (Users: 0, Guests: 0)

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice
  • About The Project

    The vision of the MediaPortal project is to create a free open source media centre application, which supports all advanced media centre functions, and is accessible to all Windows users.

    In reaching this goal we are working every day to make sure our software is one of the best.

             

  • Support MediaPortal!

    The team works very hard to make sure the community is running the best HTPC-software. We give away MediaPortal for free but hosting and software is not for us.

    Care to support our work with a few bucks? We'd really appreciate it!