Difference between revisions of ""Hello world!" w MUI"

From MorphOS Library

(Translation in progress.)
(Translation finished.)
 
Line 37: Line 37:
 
Powyższa funkcja tworzy kompletne drzewo obiektów dla naszego programu. Główny obiekt jest klasy ''Application''. Posiada obiekt podrzędny klasy ''Window''. Okno z kolei posiada obiekt główny (ang. ''root object''), który zawsze jest instancją klasy ''Group''. Wreszcie grupa główna zawiera w sobie obiekt klasy ''Text''. Przy tworzeniu obiektu aplikacji podano 6 atrybutów pełniących rolę opisową. Wartości tych artrybutów są wykorzystywane przez system w różnych miejscach. Znaczenie tych atrybutów wyjaśnione jest w dokumentacji klasy ''Application'' znajdującej się w pakiecie SDK. Znaczenie pozostałych atrybutów w sposób raczej oczywisty wynika z ich nazw, szczegóły są omówione w dokumentacji odpowiednich klas.
 
Powyższa funkcja tworzy kompletne drzewo obiektów dla naszego programu. Główny obiekt jest klasy ''Application''. Posiada obiekt podrzędny klasy ''Window''. Okno z kolei posiada obiekt główny (ang. ''root object''), który zawsze jest instancją klasy ''Group''. Wreszcie grupa główna zawiera w sobie obiekt klasy ''Text''. Przy tworzeniu obiektu aplikacji podano 6 atrybutów pełniących rolę opisową. Wartości tych artrybutów są wykorzystywane przez system w różnych miejscach. Znaczenie tych atrybutów wyjaśnione jest w dokumentacji klasy ''Application'' znajdującej się w pakiecie SDK. Znaczenie pozostałych atrybutów w sposób raczej oczywisty wynika z ich nazw, szczegóły są omówione w dokumentacji odpowiednich klas.
  
Sposób stworzenia interfejsu graficznego w tym programie jest typowy dla MUI. Kompletne drzewo obiektów jest tworzone w jdnym dużym wywołaniu funkcji ''MUI_NewObject()'' zawierającym w sobie zagnieżdżone podwywołania. Kolejność wywoływania funkcji jest odwrotna od kolejności czytania kodu. Na początku tworzone są najgłębiej zagnieżdżone obiekty, a otrzymane wskaźniki są podawane do konstruktorów obiektów nadrzędnych.
+
Sposób stworzenia interfejsu graficznego w tym programie jest typowy dla MUI. Kompletne drzewo obiektów jest tworzone w jdnym dużym wywołaniu funkcji ''MUI_NewObject()'' zawierającym w sobie zagnieżdżone podwywołania. Kolejność wywoływania funkcji jest odwrotna od kolejności czytania kodu. Na początku tworzone są najgłębiej zagnieżdżone obiekty, a otrzymane wskaźniki są podawane do konstruktorów obiektów nadrzędnych. Ostatnim tworzonym obiektem jest obiekt aplikacji. Ten sposób tworzenia drzewa obiektów zapewnia automatyczną obsługę błędów. Jeżeli którykolwiek konstruktor nie będzie w stanie stworzyć obiektu, jego wynikiem będzie wskaźnik zerowy (''NULL''). Wskaźnik ten zostanie przekazany do konstruktora obiektu nadrzędnego, co automatycznie spowoduje błąd konstrukcji i również zwrócenie ''NULL''-a, oraz zniszczenie tych obiektów podrzędnych, które udało się stworzyć do momentu błędu. Ostatecznie wskaźnik zerowy dotrze do konstruktora obiektu aplikacji, również powodując jego błąd i zwrócenie ''NULL''-a przez główne wywołanie ''MUI_NewObject()''. W efekcie drzewo obiektów aplikacji może mieć po konstrukcji tylko dwa stany: albo jest w pełni zbudowane, albo nie jest w ogóle zbudowane, a wszystkie obiekty zostały prawidłowo zniszczone. To w zasadniczy sposób upraszcza obsługę błędów.
 
 
The function illustrates a typical way of creating a MUI interface. The complete object tree is created in one big ''MUI_NewObject()'' call containing nested sub-calls. The order of code execution is different to the order of reading. The most nested objects are created first and passed to constructors of their parents. The application object is created last. This way of creating the application also ensures automatic error handling. If any of constructors fails, it passes ''NULL'' to a parent constructor, making it fail too and then dispose all successfully constructed child objects. Finally the application constructor fails and returns ''NULL''. Then only two states of the application are possible: either the application is fully constructed, or it is not constructed at all. This behaviour greatly simplifies error handling.
 
  
 
  void notifications(void)
 
  void notifications(void)
Line 47: Line 45:
 
  }
 
  }
  
The next step is to make notifications. This simple program contains only one notification, which terminates the program after the window close gadget is clicked. MUI maps a left mouse button click on the gadget to a change of ''MUIA_Window_CloseRequest'' attribute. The notification target is the application, the ''MUIM_Application_ReturnID()'' method then passes the quit action identifier to the main loop.
+
Następny krok to ustawienie [[Programowanie sterowane zdarzeniami, notyfikacje#Notyfikacje w MUI|notyfikacji]]. Ten prosty przykład zawiera tylko jedną notyfikację, kończącą program po kliknięciu gadżetu zamknięcia okna. MUI mapuje kliknięcie lewym przyciskiem myszy w gadżet zamknięcia okna na zmianę wartości atrybutu ''MUIA_Window_CloseRequest''. Celem notyfikacji jest obiekt aplikacji, metoda ''MUIM_Application_ReturnID()'' przekazuje podany identyfikator do głównej pętli programu.
  
 
  void main_loop(void)
 
  void main_loop(void)
Line 64: Line 62:
 
  }
 
  }
  
The standard main loop has been discussed in the [[Event_Driven_Programming,_Notifications#The_Ideal_MUI_Main_Loop|previous chapter]]. The only addition is opening the window before the loop and closing it after.
+
Typowa pętla główna została omówiona w [[Programowanie sterowane zdarzeniami, notyfikacje#Idealna pętla główna|poprzednim rozdziale]]. Jedyną nowością jest otwarcie okna przed wejściem w pętlę i zamknięcie po wyjściu z niej.
  
 
  int main(void)
 
  int main(void)
Line 80: Line 78:
 
  }
 
  }
  
Finally, the main function of the program. It builds the object tree first and checks if it succeeded. In case of a fail, the program ends immediately. After all the objects are created, notifications are added and the program enters the main loop. When the loop finishes, the application object is disposed. It also disposes all its sub-objects.
+
Na koniec główna funkcja programu. Na początku tworzone jest drzewo obiektów, po czym następuje sprawdzenie czy tworzenie drzewa zakończyło się sukcesem. W przypadku błędu program natychmiast kończy swoje działanie. Jeżeli interfejs graficzny został stworzony poprawnie, ustawiane są notyfikacje, a następnie program wchodzi do głównej pętli. Po zakończeniu tejże obiekt aplikacji jest niszczony, co automatycznie powoduje zniszczenie również wszystkich obiektów podrzędnych.

Latest revision as of 08:46, 20 January 2011

Grzegorz Kraszewski


Ten artykuł w innych językach: angielski


Helloworld.png
Oto okno przykładowego programu w MUI. Program jest bardzo prosty, okno zawiera tylko jeden obiekt tekstowy i żadnych gadżetów, oprócz tych na ramce. Ilość gadżetów znajdujących się po prawej stronie górnej belki okna zależy od ustawień MUI. Kod źródłowy tego programu jest również bardzo prosty i mieści się w 60 liniach, licząc również puste linie zwiększające jego przejrzystość. W artykule kod jest rozbity na części, aby tekst był łatwiejszy w czytaniu. Dostępna jest też pełna wersja kodu gotowa do skompilowania.
#include <proto/muimaster.h>
#include <proto/intuition.h>

Zaczynamy od dołączenia plików nagłówkowych bibliotek muimaster.library i intuition.library. Warto zauważyć, że biblioteki te będą otwarte i zamknięte automatycznie.

Object *App, *Win;

Tutaj mamy globalne wskaźniki na obiekt aplikacji i obiekt okna. Trzymanie wskaźników do wielu obiektów MUI w zmiennych globalnych nie jest zbyt eleganckim stylem programowania, ale kilka to jeszcze nie tragedia, zwłaszcza w tak prostym programie.

Object* build_gui(void)
{
  App = MUI_NewObject(MUIC_Application,
    MUIA_Application_Author, (ULONG)"Grzegorz Kraszewski",
    MUIA_Application_Base, (ULONG)"HELLOWORLD",
    MUIA_Application_Copyright, (ULONG)"© 2010 Grzegorz Kraszewski",
    MUIA_Application_Description, (ULONG)"Hello World in MUI.",
    MUIA_Application_Title, (ULONG)"Hello World",
    MUIA_Application_Version, (ULONG)"$VER: HelloWorld 1.0 (16.11.2010)",
    MUIA_Application_Window, (ULONG)(Win = MUI_NewObject(MUIC_Window,
      MUIA_Window_Title, (ULONG)"Hello World",
      MUIA_Window_RootObject, MUI_NewObject(MUIC_Group,
        MUIA_Group_Child, MUI_NewObject(MUIC_Text,
          MUIA_Text_Contents, (ULONG)"Hello world!",
        TAG_END),
      TAG_END),
    TAG_END)),
  TAG_END);
}

Powyższa funkcja tworzy kompletne drzewo obiektów dla naszego programu. Główny obiekt jest klasy Application. Posiada obiekt podrzędny klasy Window. Okno z kolei posiada obiekt główny (ang. root object), który zawsze jest instancją klasy Group. Wreszcie grupa główna zawiera w sobie obiekt klasy Text. Przy tworzeniu obiektu aplikacji podano 6 atrybutów pełniących rolę opisową. Wartości tych artrybutów są wykorzystywane przez system w różnych miejscach. Znaczenie tych atrybutów wyjaśnione jest w dokumentacji klasy Application znajdującej się w pakiecie SDK. Znaczenie pozostałych atrybutów w sposób raczej oczywisty wynika z ich nazw, szczegóły są omówione w dokumentacji odpowiednich klas.

Sposób stworzenia interfejsu graficznego w tym programie jest typowy dla MUI. Kompletne drzewo obiektów jest tworzone w jdnym dużym wywołaniu funkcji MUI_NewObject() zawierającym w sobie zagnieżdżone podwywołania. Kolejność wywoływania funkcji jest odwrotna od kolejności czytania kodu. Na początku tworzone są najgłębiej zagnieżdżone obiekty, a otrzymane wskaźniki są podawane do konstruktorów obiektów nadrzędnych. Ostatnim tworzonym obiektem jest obiekt aplikacji. Ten sposób tworzenia drzewa obiektów zapewnia automatyczną obsługę błędów. Jeżeli którykolwiek konstruktor nie będzie w stanie stworzyć obiektu, jego wynikiem będzie wskaźnik zerowy (NULL). Wskaźnik ten zostanie przekazany do konstruktora obiektu nadrzędnego, co automatycznie spowoduje błąd konstrukcji i również zwrócenie NULL-a, oraz zniszczenie tych obiektów podrzędnych, które udało się stworzyć do momentu błędu. Ostatecznie wskaźnik zerowy dotrze do konstruktora obiektu aplikacji, również powodując jego błąd i zwrócenie NULL-a przez główne wywołanie MUI_NewObject(). W efekcie drzewo obiektów aplikacji może mieć po konstrukcji tylko dwa stany: albo jest w pełni zbudowane, albo nie jest w ogóle zbudowane, a wszystkie obiekty zostały prawidłowo zniszczone. To w zasadniczy sposób upraszcza obsługę błędów.

void notifications(void)
{
  DoMethod(Win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, App, 2,
   MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
}

Następny krok to ustawienie notyfikacji. Ten prosty przykład zawiera tylko jedną notyfikację, kończącą program po kliknięciu gadżetu zamknięcia okna. MUI mapuje kliknięcie lewym przyciskiem myszy w gadżet zamknięcia okna na zmianę wartości atrybutu MUIA_Window_CloseRequest. Celem notyfikacji jest obiekt aplikacji, metoda MUIM_Application_ReturnID() przekazuje podany identyfikator do głównej pętli programu.

void main_loop(void)
{
  ULONG signals = 0;

  set(Win, MUIA_Window_Open, TRUE);
			 
  while (DoMethod(App, MUIM_Application_NewInput, &signals) != MUIV_Application_ReturnID_Quit)
  {
    signals = Wait(signals | SIGBREAKF_CTRL_C);
    if (signals & SIGBREAKF_CTRL_C) break;
  }

  set(Win, MUIA_Window_Open, FALSE);
}

Typowa pętla główna została omówiona w poprzednim rozdziale. Jedyną nowością jest otwarcie okna przed wejściem w pętlę i zamknięcie po wyjściu z niej.

int main(void)
{
  App = build_gui();

  if (App)
  {
    notifications();
    main_loop();
    MUI_DisposeObject(App);
  }

  return 0;
}

Na koniec główna funkcja programu. Na początku tworzone jest drzewo obiektów, po czym następuje sprawdzenie czy tworzenie drzewa zakończyło się sukcesem. W przypadku błędu program natychmiast kończy swoje działanie. Jeżeli interfejs graficzny został stworzony poprawnie, ustawiane są notyfikacje, a następnie program wchodzi do głównej pętli. Po zakończeniu tejże obiekt aplikacji jest niszczony, co automatycznie powoduje zniszczenie również wszystkich obiektów podrzędnych.