Building Plugins:MythNotes00

From MythTV Official Wiki
Jump to: navigation, search

This plug-in shows Hello World on the screen.

  • Use XML to define layout
  • Write simple text


Important.png Note: The first plug-in is the hardest one. You need many files to create something so stupid. Anyway please don't give up. For meaningful, advanced plug-ins the most of this code stays the same.

Important.png Note: Read the MythNotes introduction Building_Plugins:MythNotes first.

C++ code

Let starts with the main C++ file. This file also stays almost the same for the most of the basic plug-ins. It's purpose is to create functions used by MythTV to interfere with it.

Required functions are

  • int mythplugin_init(const char *libversion)
  • int mythplugin_run()

The mythplugin_init should check and initialize the plug-in during the MythTV start-up. Without successful initialization the plug-in is not shown in the menu. In this example the function is simplified and always returns 0 (OK).

The purpose of mythplugin_run() is to create the plug-in's main menu when it's executed from MythTV's menu. Usually the structure of this function stays the same, only the window object is changed.

There is one more catch you will see in the code. Usually the mythplugin_init function uses a wrapper function. Get used to it, we'll use it later.


Script.png /mythnotes/main.cpp

/*
 * Main of MythTV's demonstration plugin MythNotes
 *
 * Copyright (C) 2010 Lukas Doktor <ldoktor@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 */

#include <iostream>
using namespace std;

#include <QApplication>

#include "notesUI.h"

#include <mythversion.h>
#include <mythpluginapi.h>
#include <mythscreentype.h>
#include <mythuihelper.h>
#include <mythmainwindow.h>

/* Main program run wrappers */
void runNotes(void);
int  RunNotes(void);

/* UNCOMPLETED plugin initialization, see following examples */
int mythplugin_init(const char *libversion)
{
    return 0;
}

/* plugin execution wrapper */
void runNotes(void)
{
    RunNotes();
}

/* plugin execution wrapper */
int RunNotes(void)
{
    MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
    NotesUI *notes = new NotesUI(mainStack, "Notes");
    
    if (notes->Create())
    {
        mainStack->AddScreen(notes);
        return 0;
    } else {
        delete notes;
        return -1;
    }
}

/* plugin execution */
int mythplugin_run(void)
{
    return RunNotes();
}

As notified above the mythplugin_init() function only tells the MythTV that everything is all right.

The mythplugin_run() function uses RunNotes() wrapper function. This function creates new NotesUI window (described below) and if successfully created it insert it over the MythMainWindow. Otherwise it returns "-1" (error) and MythTV itself notifies the user about the failure.

And now the real code - the NotesUI:


Script.png /mythnotes/notesUI.h

/*
 * Header file for UI
 *
 * Copyright (C) 2010 Lukas Doktor <ldoktor@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 */

#ifndef NOTESUI_H_
#define NOTESUI_H_

#include "notesUI.h"

#include <mythscreentype.h>
#include <mythmainwindow.h>
#include <mythdb.h>
#include <mythdialogbox.h>

class NotesUI : public MythScreenType
{
	Q_OBJECT

  public:
	NotesUI(MythScreenStack *parentStack, QString name = "MythNotes");
	bool Create();

  private:
	MythUIText		*m_title;
};

#endif /* NOTESUI_H_ */

The NotesUI window inherits from MythScreenType which is a generic window.

To create the window two functions are required - constructor and an actual window initialization.

The private variable m_title will be used for the UI handling. The objects from the UI XML file will be assign with these variables.


Script.png /mythnotes/notesUI.cpp

/*
 * Source file for UIs
 *
 * Copyright (C) 2010 Lukas Doktor <ldoktor@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 */

#include "notesUI.h"

NotesUI::NotesUI(MythScreenStack *parent, QString name)
		: MythScreenType(parent, name), m_title(NULL)
{
}

bool NotesUI::Create()
{
	if (!LoadWindowFromXML("notes-ui.xml", "notesui", this))
		return false;

	bool err = false;
	UIUtilE::Assign(this, m_title, "title", &err);
	if (err)
		return false;

	return true;
}

The constructor only executes the parent constructor and initializes the variable objects as NULL.

The Create() function:

  • First loads the "notesui" window from the "notes-ui.xml" file. MythTV uses a logic to find this file in many locations according to aspect ratio and preferences
  • The Assign function says that object named "title" from XML file corresponds with the variable "m_title". Be careful that the object type is defined in code by variable type (MythUIText in our case) and in the XML file (textarea). You can sometimes match different types which can be confusing.
  • returns true when OK (so the main.cpp can display this screen)

UI files

The UI is defined by XML files. Let's create the basic one.


Script.png /theme/default/notes-ui.xml

<?xml version="1.0" encoding="utf-8"?>
<mythuitheme>
    <window name="notesui">
        <textarea name="title">
            <area>0,0,-1,-1</area>
            <font>large</font>
            <align>allcenter</align>
            <multiline>yes</multiline>
            <value>Hello World</value>
        </textarea>
    </window>
</mythuitheme>
  • mythuitheme tag says this XML file contain something like MythTV's theme definition :-)
  • window tag is used to define window. You can define multiple windows inside one mythuitheme
  • anything else is same as standard XML files (for more info see MythUI_Theme_Development)

You can create similar file and place it into "themes/default-wide/" location to define 16:9 layout. Anyway if the MythTV runs as 16:9 and won't find the wide UI XML file, it automatically searches for 4:3. Still in the production version always create booth.

Remaining files

I promised there will be many similar files. It's time to change the first one :-D


Script.png /mythnotes/mythnotes.pro

include ( ../../mythconfig.mak )
include ( ../../settings.pro )
include ( ../../programs-libs.pro )

TEMPLATE = lib
CONFIG += plugin \
    thread
TARGET = mythnotes
target.path = $${LIBDIR}/mythtv/plugins
INSTALLS += target
INCLUDEPATH += $${PREFIX}/include/mythtv/libmythui

# Input
HEADERS += notesUI.h
SOURCES += notesUI.cpp \
    main.cpp
QT += sql \
    xml \
    opengl
include ( ../../libs-targetfix.pro )
  • the only change is in HEADERS and SOURCES. You have to specify all the files used in the project. Otherwise it won't compile or even worse - it compiles, runs, but unexpectedly says "Unknown symbol..." or similar error. Be careful with this it has cost me a lots of time...

Compile

Now when you have all the "mythnotes" files in the $mythplugins_root directory:

cd mythnotes
qmake    # Uses the *.pro files to create the Makefile files (If you have qt3 as default you might need to run "qmake-qt4"; sometimes you have to use recursive "qmake-qt4 -r")
make    # Use the Makefiles to compile the project
make install    # To install the library and theme files.

Before you start MythTV check the "/usr/share/mythtv/themes/defaultmenu/mainmenu.xml" file. You have to modify as explained in Building_Plugins:MythNotes.

Recapitulation

  • download the mythplugins SVN and run ./configure
  • create "mythnotes" directory inside the mythplugins
  • create the default files inside the "mythnotes" directory (Building_Plugins:MythNotes)
  • create the C++ code
  • create the XML UI layout
  • modify the "mythnotes/mythnotes.pro" file
  • add the mythnotes button into the MythTV's Main Menu ("/usr/share/mythtv/themes/defaultmenu/mainmenu.xml")
  • compile

Hello World!

execute the mythtvfrontend

You should find in the main menu the MythNotes button and by pressing it you should see the Hello World window. (use escape to get rid of it)

Debug

When something goes wrong use:

LOG(VB_GENERAL, LOG_ERR, "YOUR TEXT");

in the C++ code (defined in <mythlogging.h>, so be sure to include the header if you use it). Then when you execute the mythfrontend in the console, you'll see the messages.

Additionally you can use mythfrontend -v all to enable more verbose level (you can specify multiple levels separated by ',').

Next tutorial

Important.png Note: You have successfully finished the Hello World tutorial. Let's move on to the next level - "Basic UI" (Building_Plugins:MythNotes01)