Grafische Oberflächen für die Konsole von Microsoft

Widgets für die Xbox 360 (Teil 2)
Kommentare

Microsoft predigt seit Jahren, dass Silverlight die Zukunft ist. Denn wer sein GUI mit Silverlight programmiert, kann es angeblich auf allen Microsoft-Plattformen verwenden. Doch stimmt das auch?

Es werde Form

Obwohl der Mauszeiger zweifellos adrett aussieht, ist es nicht der Sinn eines GUI-Frameworks, einen Mauszeiger auf den Bildschirm zu malen. Viel schöner wäre es, ein Formular samt einiger Steuerelemente loszulassen. Formulare werden in orbUI als von OrbUI.Components.GUI.Controls.Form abgeleitete Klassen implementiert. Ein absolut primitives Skelett würde folgendermaßen aussehen:

class MainForm: OrbUI.Components.GUI.Controls.Form
{
public MainForm()
: base(„MainFormTag“, „Main Form“, new Point(30, 30), new Point(700, 550), OrbUI.Components.GUI.FormBorderStyle.Fixed)
{

Show();
}
}

Obwohl diese Klassendeklaration vergleichsweise lang ist, ist sie doch vollkommen primitiv. Die Klasse wird von der Basisklasse vererbt. Beim Aufruf ihres Konstruktors wird der Konstruktor der Basisklasse verkettet. Die dabei auftretenden vier Parameter werden bei so gut wie jedem Steuerelement erforderlich werden. Der erste String ist das Tag des Controls, mit dem man es später identifizieren kann. Unter keinen Umständen dürfen zwei Steuerelemente in einem Formular (oder zwei Formulare in einer Anwendung) den gleichen Tag besitzen. Der zweite Parameter gibt den Titel des Formulars an, während die Parameter drei und vier die Größe und Position des Formulars festlegen. Im Konstruktor wird Show() aufgerufen. Wie unter Visual Basic 6 wird das Formular dann auf den Bildschirm gezeichnet und als aktives Formular festgelegt. Im Code wird unser Formular in LoadContent aktiviert:

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
MainForm x = new MainForm();
}

Auch hier ist eigentlich alles ganz einfach: Nachdem das Skelett seinen SpriteBatch erstellt hat, wird eine Instanz unseres Formulars kreiert.

Steuerelemente

Im nächsten Schritt werden wir unser Formular um einige Steuerelemente ergänzen, im Speziellen um zwei Textboxen, ein Label, zwei Radiobuttons und zwei Knöpfe; Es geht also um einen simplen Taschenrechner. In orbUI werden Formulare vollständig in Code realisiert. Das erinnert zwar auf den ersten Blick an Qt, nur gibt es leider keinen Designer für orbUI-Interfaces. Daher ist es sinnvoll, das Interface im ersten Schritt grob auf kariertem Papier zu skizzieren (Abb. 1). Danach tut man sich beim Implementieren wesentlich leichter. Eine vom Autor erprobte und für gut befundene Vorgehensweise dabei ist, im ersten Schritt das Formular eins zu eins mit den im karierten Papier anzumessenden Werten zu erstellen und noch ohne verdrahtete Event Handler auf die Xbox zu jagen. Dort sieht man schnell, wo es hakt, und kann die Koordinaten von Hand adjustieren. In unserem Beispiel sähe die finale Erstellungsroutine wie in Listing 3 aus.

Abb. 1: Unsere Anwendung auf kariertem Papier
Abb. 1: Unsere Anwendung auf kariertem Papier
Listing 3
public MainForm()
    : base("MainFormTag", "Main Form", new Point(30, 30), new Point(700, 550), OrbUI.Components.GUI.FormBorderStyle.Fixed)
    {

      LblResult = new Label("LblResult", new Point(200 * 2 + 150, 125), new Point(125, 50), "", Color.Black);
      Controls.Add(LblResult);

      Txt1 = new TextBox("Txt1", new Point(50, 25), new Point(200, 50));
      Controls.Add(Txt1);

      Txt2 = new TextBox("Txt2", new Point(200+100, 25), new Point(200, 50));
      Controls.Add(Txt2);

      CmdCalc = new Button("CmdCalc", new Point(200*2 + 150, 25), 125, "Rechne!", Color.Black);
      CmdCalc.CursorUp += CmdHandler;
      Controls.Add(CmdCalc);

      CmdAbout = new Button("CmdAbout", new Point(275, 200), 170, "Was ist das?", Color.Black);
      CmdAbout.CursorUp += CmdHandler;
      Controls.Add(CmdAbout);

      RbtAdd = new RadioButton("RbtAdd", "Addiere", new Point(50, 125), new Point(200, 50), true);

      Controls.Add(RbtAdd);

      RbtSubtract = new RadioButton("RbtSubtract", "Subtrahiere", new Point(200 + 100, 125), new Point(200, 50), false);
      Controls.Add(RbtSubtract);

      List myRBTs = new List();
      myRBTs.Add(RbtAdd);
      myRBTs.Add(RbtSubtract);
      RadioButtonGroup myGroup = new RadioButtonGroup("rbtgroup", new Point(50, 125), new Point(500, 50), myRBTs);

      Controls.Add(myGroup);

      myKeyboard = new OnScreenKeyboard("myKeyboard", "", new Point((800 - OrbResources.Control_OnScreenKeyboard_Size.X) / 2, 600 - OrbResources.Control_OnScreenKeyboard_Size.Y));
      myKeyboard.ShowDialog();

      Show();
    }
  

Obwohl der Code des Konstruktors extrem umfangreich ist, ist er doch sehr einfach. Jedes Steuerelement wird durch eine Instanz der „Basisklasse“ abgebildet, die zwecks späterer Erreichbarkeit in eine Member-Variable des Formulars geschrieben wird. Danach wird jedes Steuerelement parametrisiert. Dabei ist je nach Steuerelementtyp eine andere Codesequenz erforderlich. Weitere Informationen befinden sich in der Dokumentation des Frameworks. Erwähnenswert ist der Aufbau der Radiobuttons: Sie müssen nämlich in Gruppen eingeteilt werden, sodass immer nur einer von ihnen aktiv sein kann. Das wird über die RadioButtonGroup erreicht, deren Extent mehr oder minder der von ihren Buttons enthaltenen Fläche entsprechen muss. Zuletzt werden alle Steuerelementinstanzen zum Formular hinzugefügt. Der Aufruf von Show() wurde schon im vorherigen Beispiel erklärt und dient zum Anzeigen des Formulars auf dem Bildschirm. Damit fehlen nur mehr die Event-Handler-Routinen. Sie werden als Methoden des Formulars realisiert – auch hier dient als Beispiel der Code unseres kleinen Taschenrechners (Listing 4). Interessant ist hier die Selektion für die Command-Buttons, beide Knöpfe sind nämlich mit ein- und derselben Routine verbunden. Deshalb muss man die Events in der Routine „auseinanderdividieren“, bevor man sie verarbeitet. Die Erstellung des zweiten Formulars ist erst später von Bedeutung.

Listing 4
private void CmdHandler(object sender)
{
    if (sender == CmdAbout)
    {
      AboutForm x = new AboutForm();
    } else {
      Double text1 = Convert.ToDouble(Txt1.Text);
      Double text2 = Convert.ToDouble(Txt2.Text);
      if (RbtAdd.Checked == true)
      {
        LblResult.Text = Convert.ToString(text1 + text2);
      } else {
        LblResult.Text = Convert.ToString(text1 - text2);
      }
    }
}
  
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -