Wstep:



Kurs programówania w Haiku/BeOsię:





 

Architektura systemów Haiku/BeOS z punktu widzenia programisty

Jedną z najbardziej charakterystycznych cech systemów BeOS/Haiku jest nowoczesna architektura stworzona specjalnie na potrzeby operacji multimedialnych.

Największe zalety tej architektury to: 

  • możliwość obsługi więcej niż jednego procesora
  • doskonała wielowątkowość - system sam dzieli program na osobne wątki np. każde okno programu to oddzielny wątek posiadający własną pętlę obsługi zdarzeń. Rozwiązanie to nie tylko poprawia szybkość działania programów na systemach wieloprocesorowych, ale także zapobiega blokowaniu wszystkich okien programu podczas wykonywania skomplikowanych obliczeń. Ilość czasu procesora poświęcana danemu wątkowi, określana jest na podstawie jego priorytetu.
  • możliwość przetwarzania fonii i wizji w czasie rzeczywistym
  • bazodanowy system plików - umożliwia szybkie przeszukiwanie dysków i określanie specjalnych atrybutów dla plików.
  • obsługa dynamicznie ładowanych sterowników
  • obsługa bibliotek współdzielonych
  • tryb chroniony


Budowa systemu BeOS/Haiku:

System można podzielić na trzy podstawowe warstwy: 



  • mikrojądro, którego zadaniem jest pośredniczyć między sprzętem a warstwami wyższymi
  • serwery, których zadaniem jest wykonywanie niskopoziomowych zadań (zwykle w innych systemach wykonywanych przez aplikację).  Serwery te nie służą użytkownikowi bezpośrednio, lecz służą aplikacjom (architektura klient - serwer, aplikacja jest klientem serwera app_server)li>
  • biblioteki - biblioteki dostarczają funkcji za pomocą których możemy odwoływać się do serwerów i jądra. Funkcje te podzielone są na tzw. Software Kits, czyli partie odpowiedzialne za wykonywanie określonych operacji: 
    ´
    Software Kits:
    Application Kit dostarcza interfejs potrzebny do ustanowienia połączenia między app_server (serwerem aplikacji) a tworzoną aplikacją
    Device Kit dzieli się na dwie części, pierwsza służy do tworzenia sterowników urządzeń, druga dostarcza funkcje do obsługi urządzeń takich jak joystick, serial port
    Game Kit zawiera funkcje ułatwiające tworzenie gier
    Interface Kit dostarcza interfejs wykorzystywany do tworzenia graficznych interfejsów użytkownika
    Kernel Kit zawiera funkcję do zarządzania wątkami, pamięcią itd.
    Media Kit dostarcza interfejs wykorzystywany przy przetwarzaniu informacji w czasie rzeczywistym, ze szczególnym uwzględnieniem danych graficznych i dźwiękowych
    Midi Kit dostarcza interfejs wykorzystywany przy przetwarzaniu danych MIDI
    Network Kit zawiera funkcje pozwalające ustanawiać połączenia TCP i UDP.
    OpenGL Kit dostarcza interfejs OpenGL wykorzystywany do tworzenia grafiki 3D
    Translation Kit zawiera funkcje pozwalające napisać własny translator umożliwiający zmianę formatów plików
    Storage Kit dostarcza interfejsu (funkcji) wykorzystywanych przy operacjach zapisu/odczytu/przeszukiwania danych zapisanych na dyskach
    Support Kit zawiera funkcje i typy danych wykorzystywane w innych modułach (Kits)


Ogromna większość interfejsu programistycznego BeOS-a została napisana w obiektowym C++ np. okno określone jest za pomocą klasy BWindow. Jedynie Kernel Kit nie dostarcza obiektowego interfejsu. BeOS słynie z przejrzystego i łatwego do zrozumienia API. 


wróc do indeksu


 

BeIDE - szybki start

Standardowym środowiskiem programistycznym dla BeOSa jest BeIDE. Przed rozpoczęciem programowania, dobrze więc byłoby przyjrzeć się rozwiązaniom ułatwiającym (i przyspieszającym) pisanie programów, oraz poznać podstawowe skróty klawiszowe. 

Tworzenie nowego projektu:

Zaraz po uruchomieniu BeIDE naszym oczom ukazuje się czyste okno edycyjne (patrz Rys.1) , aby rozpocząć nowy projekt wybieramy polecenie New Project z menu File. 

Rys.1 Puste okno edycyjne



Następnym pytaniem na które musimy odpowiedzieć jest rodzaj projektu (Rys.2). Do wyboru mamy: 


  • tworzenie aplikacji (BeApp - dla platformy PC lub ppc_BeApp - dla platformy Mac)
  • tworzenie aplikacji tekstowej (BeSTL)
  • tworzenie sterownika (KernelDriver)
  • tworzenie biblioteki współdzielonej (SharedLibrary)
  • tworzenie biblioteki statycznej (StaticLibrary)
  • lub pusty projekt (Empty Project)

 

Rys.2 Okno wyboru typu projektu.

Następnie jesteśmy proszeni o wybranie miejsca w którym będą składowane pliki projektu. Jeżeli w okienku Nowego projektu (Rys.2) była zaznaczona opcja Create Folder, to przed zapisaniem pliku projektu tworzony jest katalog dla niego. 
Jeżeli jako rodzaj projektu wybraliśmy aplikacje BeOSa (BeApp) standardowo są do niego dołączane biblioteki libroot.so i libbe.so. W tym momencie nasz projekt nie posiada jeszcze żadnych plików źródłowych. 

Rys.3 Okno zarządzania projektem.



Dodawanie plików do projektu:

Plik źródłowy do projektu można dodać na trzy sposoby. Z poziomu okna edycyjnego zaznaczając opcję Add to project podczas pierwszego zapisywania pliku lub jeżeli plik był już zapisywany, za pomocą polecenia Add To Project z menu Project. Trzecim sposobem jest polecenie Add Files... z menu Project głównego okna projektu (Rys.3). 

Kompilacja i konsolidacja:

Do kompilacji służy polecenie Compile z menu Project, aby skonsolidować program używamy polecenia Link z tego samego menu. 
Aby skompilować i z linkować projekt wybieramy polecenie make, plik wykonywalny (jeżeli tworzymy aplikację) zostanie stworzony w katalogu naszego projektu. 

Skróty klawiszowe i udogodnienia dla programistów dostępne podczas edycji kodu źródłowego

Okno edycyjne BeIDE jest zwykłym edytorem tekstu, obsługującym dodatkowo funkcje ułatwiające nawigację i edycję kodu źródłowego. BeIDE jest środowiskiem w pełni konfigurowalnym (można dowolnie zmienić czcionkę, sposób podświetlania składni języka C++). 

Najważniejszymi funkcjami ułatwiającymi nawigację po kodzie źródłowym jest funkcja skoku do metody uruchamiana przez ikonkę {} w lewym dolnym rogu okna edycyjnego oraz funkcja Go To Line pozwalająca skoczyć do dowolnej linii w pliku źródłowym. 

Rys.4 Bardzo pomocna funkcja: skok do metody.



Położenie okna edycyjnego możemy ustawiać za pomocą funkcji dostępnych z menu Window. 

A oto najważniejsze skróty klawiszowe: 

Najważniejsze skróty klawiszowe:
Ctrl + 0 wyświetlenie okna zarządzania projektem
Ctrl + I wyświetlenie okna błędów i komunikatów kompilacji
Ctrl + Z Undo (cofnij)
Ctrl + Shift + Z Redo
Ctrl + x wytnij
Ctrl + c kopiuj
Ctrl + v wklej
Ctrl + A zaznacz wszystko
Ctrl + B zaznaczenie bloku tekstu (od "{" do "}")
Ctrl + [ przesuniecie w lewo
Ctrl + ] przesuniecie w prawo
Ctrl + F znajdź
Ctrl + G znajdź następne
Ctrl + T znajdź w następnym pliku
Ctrl + H znajdź zaznaczone
Ctrl + = znajdź i zamień
Ctrl + L zamień i znajdź następne
Ctrl + , skocz do linii
Ctrl + K kompiluj
Ctrl + ; sprawdź składnie
Ctrl + U aktualizuj datę ostatniej modyfikacji pliku
Ctrl + M Make
Ctrl + / powiększ okno
Ctrl + N nowe okno edycyjne
Ctrl + Shift + N nowy projekt
Ctrl + O otwórz plik
Ctrl + S zapisz plik
Ctrl + W zamknij plik



UWAGA!

BeIDE nie jest domyślnym środowiskiem programistycznym dla systemu Haiku (jako takie jeszcze nie istnieje). W Haiku domyślnie używane jest jedynie narzędzie jam. Mino to zdecydowałem się użyć BeIDE ponieważ jest to najwygodniejsze środowisko programistyczne dla BeOSa. 

wróc do indeksu


 

Część 1 - pierwszy program:

Jak już pisałem w artykule na temat architektury systemu [Link], API Haiku/BeOSa w przeważającej większości zostało napisane w C++. Zostało także podzielone na logiczne części (tzw "Software Kits") odpowiadające za różne zadania. 

Praktycznie każda aplikacja korzysta z Application Kit czyli modułu, którego podstawowym zadaniem jest stworzenie obiektu aplikacji i połączenie go z serwerem aplikacji tzw. app_server-em. 

Tworzenie projektu:

BeIDE dokładniej omówiłem w tekście "BeIDE - szybki start" [Link  ], w tym miejscu tylko krótkie przypomnienie: 

Po uruchomieniu BeIDE wybieramy z menu File polecenie New Project, po czym jesteśmy proszeni o: 

  • wybranie rodzaju projektu, w naszym wypadku wybieramy BeApp
  • zapisanie pliku projektu, w naszym przypadku plik projektu nazwiemy PierwszaApp.proj


Po wykonaniu tych operacji wracamy do okna edycyjnego i zapisujemy pusty plik pod nazwą main.cpp w katalogu naszego projektu, zaznaczając opcję Add To Project. 
Teraz jesteśmy gotowi napisać swój pierwszy program dla Haiku/BeOSa. 

Tworzenie aplikacji:

Na początku tworzenia programu musimy stworzyć obiekt aplikacji. Klasa definiująca ten obiekt dostępna jest w Applicaton Kit należy więc dodać plik nagłówkowy Application.h lub bardziej ogólny AppKit.h: 

#include <Application.h>


Obiekt aplikacji reprezentuje klasa BApplication, ale zwykle korzystamy z dziedziczenia, czyli nie tworzymy obiektu typu BApplication lecz tworzymy klasę opartą na BApplication. Postępujemy tak ponieważ klasa BApplication zawiera funkcje wirtualne, które będziemy chcieli później przesłonić. 
Naszą klasę obiektu aplikacji nazwiemy PierwszaApp: 

class PierwszaApp : public BApplication { 
public : 
PierwszaApp():BApplication("application/pierwszaapp") 
    { 
    } 
};


Klasa PierwszaApp wywołuje konstruktor klasy BApplication z jednym parametrem. Tym parametrem jest sygnatura aplikacji. Sygnatura aplikacji pozwala na jednoznaczne określenie naszej aplikacji przez system operacyjny. Sygnatura ta musi zaczynać się tekstem application/ i jest nadpisywana przez sygnaturę podaną w pliku zasobów stworzonym w aplikacji FileTypes (jeżeli taki plik wogóle dodamy, o plikach zasobów dowiemy się więcej później). 
Po stworzeniu klasy poprostu tworzymy jej obiekt w funkcji main() za pomocą operatora new, a następnie uruchamiamy pętlę obsługi zdarzeń za pomocą funkcji Run(): 

int main() 
{ 
new PierwszaApp; //stworzenie obiektu aplikacji 
be_app->Run(); // uruchomienie petli obsługi zdarzeń 
delete be_app; // usuniecie obiektu aplikacji 
}

Każda aplikacja może mieć tylko jeden obiekt aplikacji, który jest automatycznie przydzielany do wskaźnika be_app w konstruktorze klasy BApplication (dlatego nie musimy umieszczać nazwy wskaźnika przed operatorem new). 
Przed samym zakończeniem działania programu musimy usunąć obiekt aplikacji: 

delete be_app;


Cały program wygląda następująco: 

 

//main.cpp 

#include <Application.h> 

class PierwszaApp : public BApplication 
    { 
    public : 
    PierwszaApp():BApplication("application/pierwszaapp") 
        { 
        } 
    }; 

int main() 
    { 
    new PierwszaApp; //stworzenie obiektu aplikacji 
    be_app->Run(); // uruchomienie pętli obsługi zdarzeń 
    delete be_app; // usunięcie obiektu aplikacji 
    }


Aby skompilować i z linkować program używamy skrótu klawiszowego Ctrl + m lub polecenia Make z menu Project. 
Plik wykonywalny będzie miał nazwę BeApp, chyba że zmieniliśmy jego nazwę w preferencjach projektu (okno zarządzania projektem, menu Edit->Project Settings zakładka x86 ELF Project). 
Uruchomienie naszego programu nie robi właściwie nic poza stworzeniem aplikacji i zajęciem miejsca na pasku zadań. 
Powyższy program można ściągnąć tutaj [
Link ]. 

wróc do indeksu


 

Część 2 - Pliki zasobów (FileTypes)

Ta część, kursu niewiele będzie miała wspólnego z kodowaniem. Zajmiemy się określeniem sposobu współpracy naszej aplikacji z systemem operacyjnym. Określimy takie podstawowe cechy jak sposób uruchomienia, obsługiwane typy plików, oraz dodamy ikonę i opis wyświetlany przez trackera. 
Wszystkie powyższe cechy aplikacji w BeOSie ustalamy tworząc specjalny plik zasobów za pomocą aplikacji File Types. 

Tworzenie pliku zasobów:

File Types jest podstawową aplikacją sytemu, zwykle znajdziemy ją w menu Preferences. 

Rys.1 Podstawowe okno aplikacji File Types.



Podstawowe okno aplikacji File Types (Rys.1) dzieli się na dwie zasadnicze części. Listę sygnatur z lewej strony i opcje dla aktualnie wybranej sygnatury z prawej strony. 

Aby stworzyć nowy plik zasobów wybieramy polecenie New Resurce File z menu File. Po czym pojawia nam się okno podobne do poniższego (ale bez wypełnionych danych i narysowanej ikonki, które umieściłem na screen-ie dla przykładu) : 

Rys.2 Okno tworzenia nowego pliku zasobów (z przykładowymi danymi).



Na początku wpisujemy sygnaturę naszej aplikacji. Sygnatura pozwala systemowi operacyjnemu jednoznacznie zidentyfikować aplikację. Należy pamiętać że sygnatura aplikacji musi się zaczynać od tekstu application/ i że sygnatura wpisana w pliku zasobów zastępuje tą podaną w konstruktorze klasy BApplication. 

Poniżej pola sygnatury możemy ustawić opcje aplikacji takie jak: 

  • sposób uruchomienia (działania),
  • obsługiwane typy plików
  • informacje o wersji i opis


Dołączenie ikonki:

W prawym górnym rogu znajduje się szary kwadrat. Dwukrotne kliknięcie na nim otwiera aplikacje Icon-O-Matic (Rys.3) pozwalającą nam narysować ikonę dla aplikacji. 

Rys.3 Program Icon-O-Matic.



Po zakończeniu rysowania zapisujemy ikonę za pomocą polecenia save i zamykamy okno Icon-O-Matic. Podobnie możemy dodać ikonę dla każdego obsługiwanego typu plików.
Po narysowaniu ikonki i ustawieniu wszystkich opcji zgodnie z naszymi oczekiwaniami, plik zasobów zapisujemy za pomocą polecenia File->Save into resurce file. 

Dołączenie pliku zasobów do projektu w BeIDE:

Nasz zapisany plik zasobów powinien mieć rozszerzenie .rsrc i najlepiej jakby znajdował się w katalogu naszego projektu. Samo dodanie pliku do projektu nie różni się niczym od dołączenia pliku źródłowego. Używamy polecenia Add Files.. z menu Project. Uwzględnienie zmian wymaga rekompilacji projektu. Po wykonaniu rekompilacji i rekonsolidacji nasza aplikacja otrzyma ikonkę i będzie działała zgodnie z opcjami ustalonymi w pliku zasobów. 
Przykładowy plik zasobów można pobrać stąd [
Link ]. 

wróc do indeksu


 

Część 3 - pierwsze okno

Po "lekkiej" drugiej części kursu czas wrócić do prawdziwego kodowania. 
Ponieważ BeOS jest systemem operacyjnym, którego głównym sposobem komunikowania się z użytkownikiem jest graficzny interfejs użytkownika (GUI). Dobrze byłoby nauczyć się tworzyć okna. 

Klasą definiującą obiekt okna w BeOsie jest BWindow. Obiekty okien w BeOSie możemy tworzyć dopiero po stworzeniu obiektu aplikacji (o tworzeniu obiektu aplikacji pisałem w pierwszej części kursu). 

Konstruktor klasy BWindow:

Klasa BWindow posiada kilka różnych konstruktorów, oto dwa najczęściej stosowane: 

BWindow( BRect frame, const char * title, window_type type, uint32 flags, uint32 workspaces = B_CURRENT_WORKSPACE);
BWindow(BRect frame, const char * title,window_look look,window_feel feel, uint32 flags, uint32 workspace = B_CURRENT_WORKSPACE);


Opis argumentów: 


  • frame - obiekt typu BRect określający rozmiar obszaru roboczego okna i jego położenie.  Obiekty klasy BRect stosowane są wszędzie tam gdzie trzeba określić jakiś prostokątny obszar. Klasa BRect opiera się on na czterech podstawowych polach danych:  float left - odległość lewej krawędzi prostokąta od lewej krawędzi ekranu  float top - odległość górnej krawędzi prostokąta od górnej krawędzi ekranu  float right - szerokość prostokąta  float bottom - wysokość prostokąta  Do tworzenia obiektów BRect zwykle wykorzystujemy poniższy konstruktor, przyjmujący cztery argumenty określające wartość każdego pola danych:  BRect(float left, float top, float right, float bottom) czyli opisanie prostokąta odległego o 20 punktów od lewej krawędzi ekranu, o 30 od górnej krawędzi ekranu i rozmiarach szerokość 400, wysokość 200 będzie wyglądało następująco:  BRect Prostokat(20,30,400,200);
  • title - łańcuch znaków określający tytuł okna
  • look - flaga określająca wygląd okna:  B_DOCUMENT_WINDOW_LOOK - duży pasek tytułu, grube obramowanie, duży kwadrat do zmiany rozmiaru okna w prawym dolnym rogu: 
    B_TITLED_WINDOW_LOOK - to samo co wyżej ale kwadrat do zmiany rozmiaru został zastąpiony wyznaczeniem części obramowania okna: 
    B_FLOATING_WINDOW_LOOK - mały pasek tytułu, wąskie obramowanie, prawy dolny róg obramowania służy do zmiany rozmiaru okna: 
    B_MODAL_WINDOW_LOOK - brak pasku tytułowego, grube obramowanie, brak kontrolki zmiany rozmiaru okna: okna: 
    B_BORDERED_WINDOW_LOOK - brak paska tyułowego, obramowanie, brak kontrolki zmiany rozmiaru okna: 
    B_NO_BORDER_WINDOW_LOOK - brak wszelkich ozdób okna
  • feel - określa zachowanie okna, najważniejsze wartości to: 
    Najważniejsze wartości dla argumentu feel
    B_NORMAL_WINDOW_FEEL okno zachowuje się normalnie
    B_FLOATING_ALL_WINDOW_FEEL okno występuje zawsze na wierzchu, na wszystkich pulpitach
    B_MODAL_ALL_WINDOW_FEEL okno występuje na zawsze na wierzchu, blokuje dostęp do wszystkich innych na wszystkich pulpitach
  • type - argument zastępujący feel i look w drugim konstruktorze, tak naprawdę jest to kombinacja wartości feel i look, najważniejsze wartości to: 
    Najważniejsze wartości dla argumentu type
    B_TITLED_WINDOW okno wyglądające jak B_TITLED_WINDOW_LOOK i zachowujące się normalnie (B_NORMAL_WINDOW_FEEL)
    B_DOCUMENT_WINDOW okno wyglądające jak B_DOCUMENT_WINDOW_LOOK i zachowujące się normalnie (B_NORMAL_WINDOW_FEEL)
    B_MODAL_WINDOW okno wyglądające jak B_MODAL_WINDOW_LOOK i blokujące dostęp do wszystkich innych okien aplikacji (B_MODAL_APP_WINDOW_FEEL)
    B_BORDERED_WINDOW okno wyglądające jak B_BORDERED_WINDOW_LOOK i zachowujące się normalnie
    B_UNTYPED_WINDOW okno o nieznanym typie
  • flags - parametr ten określa inne opcje okna np. czy użytkownik może powiększyć okno itp. Najważniejsze wartości: 
    Najważniejsze wartości dla argumentu flags
    B_NOT_MOVABLE nie pozwala przemieścić okna
    B_NOT_CLOsąBLE utworzone okno nie posiada przycisku zamknij na pasku tytułowym
    B_NOT_ZOOMABLE utworzone okno nie posiada przycisku maksymalizuj(zoom) na pasku tytułowym
    B_NOT_MINIMIZABLE nie pozwala zminimalizować okna przez podwójne kliknięcie w pasek tytułowy
    B_NOT_H_RESIZABLE nie pozwala zmieniać rozmiaru okna w poziomie
    B_NOT_V_RESIZABLE nie pozwala zmieniać rozmiaru okna w pionie
    B_NOT_RESIZABLE nie pozwala zmieniać rozmiaru okna w żadnym kierunku
  • workspaces - określa pulpit na którym ma być widoczne okno, najważniejsze wartości to: 
    Najważniejsze wartości dla argumentu workspaces
    B_CURRENT_WORKSPACE okno ukaże się na aktywnym pulpicie
    B_ALL_WORKSPACES okno będzie widoczne na wszystkich pulpitach

Jak widać możliwości jest naprawdę dużo, a i tak przedstawiłem jedynie te najważniejsze. 

Tworzenie okna: 

Stwórzmy więc własną klasę okna (opartą na BWindow), która będzie służyła do utworzenia normalnego okna o rozmiarze 300x200 zaczynając od punktu 20,20. 

Na początku musimy dodać plik nagłówkowy Window.h: 

#include<Window.h>


Następnie stworzyć obiekt typu BRect określający obszar roboczy okna: 


BRect obszarokna(20,20,300,200);


Teraz definiujemy naszą klasę okna: 


 
class PierwszeOkno : public BWindow 
{ 
public: 
PierwszeOkno():BWindow(obszarokna,"Pierwsze okno",B_TITLED_WINDOW,0,B_CURRENT_WORKSPACE)
    { 
    } 
};


Później tworzymy wskaźnik typu PierwszeOkno: 

PierwszeOkno * POkno;



Ostatnim krokiem tworzenia okna jest utworzenie obiektu za pomocą operatora new. Zrobimy to w funkcji main() zaraz po stworzeniu obiektu aplikacji (obiekt aplikacji musi być tworzony wcześniej). 


POkno = new PierwszeOkno;


Pełny kod programu wygląda następująco: 

//main.cpp 
#include≶Application.h> 
#include<Window.h> 

BRect obszarokna(20,20,300,200); 

class PierwszeOkno : public BWindow 
    { 
    public: 
    PierwszeOkno():BWindow(obszarokna,"Pierwsze okno",B_TITLED_WINDOW,0,B_CURRENT_WORKSPACE)
        { 
        } 
    }; 

PierwszeOkno * POkno; 

class PierwszaApp : public BApplication 
    { 
    public: 
    PierwszaApp():BApplication("application/pierwszaapp_z_oknem") 
        { 
        } 
    }; 

int main() 
    { 
    new PierwszaApp; 
    POkno = new PierwszeOkno; 
    POkno->Show(); 
    be_app->Run(); 
    delete be_app; 
    }

 


W programie występuje jedna nieznana prędzej funkcja - Show() z klasy BWindow. Zadaniem tej funkcji jest wyświetlenie okna. 

Nasza aplikacja ma małe niedociągnięcie. Zamknięcie okna nie kończy aplikacji, jak rozwiązać ten problem i jeszcze więcej na temat okien w BeOSie w następnej części kursu. 

Okno programu przykładowego powinno wyglądać następująco: 

Rys.1 Program przykładowy Okno 1.0.



Program przykładowy "PierwszeOkno" można pobrać stąd [
Link ]. 

wróc do indeksu


 

Cz??? 4 - Komunikaty systemowe i funkcje wirtualne

Ta część kursu zaczniemy od uporządkowania i podzielenia naszego kodu źródłowego. Definicje klas umieścimy w specjalnie stworzonych plikach naglówkowych, a cala operacje tworzenia okna wrzucimy do konstruktora naszej klasy aplikacji. 

Definicje klasy naszego okna wrzucimy do pliku PierwszeOkno.h , definicje klasy aplikacji do PierwszaApp.h . Wszystkie definicje funkcji okna bedziemy zapisywac w pliku  PierwszeOkno.cpp . Funkcja main()  i funkcję aplikacji będą znajdowac się w pliku PierwszaApp.cpp

Przed rozpoczęciem modularyzacji kodu warto, wtracic male przypomnienie: 

W plikach naglówkowych korzystamy z makro definicji preprocesora aby zapobiec wielokrotnemu wlaczeniu tego sąmego kodu. 
Algorytm sprawdźajacy czy dany kod zostal już wlaczony jest bardzo prosty. Najpierw sprawdźamy czy istnieje jakies makro za pomocą dyrektywy #ifndef Jeżeli nie to definiujemy je za pomocą dyrektywy #define  i dodajemy nasze definicje, deklaracje. Jeżeli preprocesor napotka nasz plik naglówkowy drugi raz dyrektywa #ifndef  nie pozwoli dolaczyc wszystkiego co znajduje się między nia a  #endif  czyli naszych deklaracji. więcej na temat modularyzacji kodu napisąlem tutaj [ Link ]. 

A więc zacznijmy od pliku naglówkowego naszego okna: 

    Plik naglówkowy 

PierwszeOkno.h

//Plik naglówkowy definiujacy klase okna. PierwszeOkno.h 
#ifndef _PIERWSZE_OKNO_H_ 
#define _PIERWSZE_OKNO_H_ 

#include<Window.h> 

extern BRect obszarokna; 

class PierwszeOkno : public BWindow 
    { 
    public: 
    PierwszeOkno():BWindow(obszarokna,"Pierwsze okno",B_TITLED_WINDOW,0,B_CURRENT_WORKSPACE)
        { 
        } 
    }; 
#endif


Plik źródłowy naszego okna bedzie narazie bardzo krótki i bedzie jedynie definiowal obiekt obszarokna: 


    Plik źródłowy 

PierwszeOkno.cpp 

//Plik źródłowy PierwszeOkno.cpp 
#include"PierwszeOkno.h" 

BRect obszarokna(20,20,300,200);
​


Klase okna mamy już zdefiniowana, czas na klase aplikacji, tutaj bedzie troche więcej zmian: 


    Plik naglówkowy 

PierwszaApp.h

//Plik naglówkowy definiujacy klase aplikacji PierwszaApp.h 
+ifndef _PIERWSZA_APP_H_ 
#define _PIERWSZA_APP_H_ 

#include <Application.h> 
#include"PierwszeOkno.h" 

class PierwszaApp : public BApplication 
    { 
    public: 
    PierwszaApp(); 
    PierwszeOkno * POkno; //wskaznik do naszego okna bedzie nalezal do 
    //aplikacji 
    }; 

#endif


Ostatnim plikiem jest PierwszaApp.cpp: 


    Plik źródłowy 

PierwszaApp.cpp 

#include"PierwszaApp.h" 

int main() 
    { 
    new PierwszaApp(); 
    be_app->Run(); 
    delete be_app; 
    } 

PierwszaApp::PierwszaApp():BApplication ("application/pierwszaapp_z_oknem") 
    { 
    POkno = new PierwszeOkno; 
    POkno->Show(); 
    }


Teraz nasz projekt Pierwsze okno, konstrukcja kodu bardziej już przypomina aplikację BeOsą, oraz bedzie o wiele latwiejszy do rozbudowy. 
Oczywiscie zmiany w podziale kodu nie wplynely na dzialanie naszego programu i nadal zamkniecie okna nie powoduje zakonczenia działania aplikacji. 

Aby zmienić zachowanie naszej aplikacji zaleznie od zdarzeń generowanych przez użytkownika (takich jak np. zamkniecie okna) musimy poznać mechanizm komunikatów systemówych BeOsą.  

Jakiekolwiek działania użytkownika na nasza aplikację powoduja wysylanie komunikatów do naszej aplikacji. Komunikaty te są obsługiwane przez specjalne funkcję tzw hook functions. 
funkcję te dzielimy na trzy rodzaje: 

  • fukcje w pełni zaimpelnetowane przez system, najczęściej przytaczanym przykladem jest klikniecie w przycisk maksymalizuj (zoom) na pasku tytulowym.
  • funkcję zainplementowane, ale których obsługa w szczególnych wypadkach moze nie byc wystarczajaca,wtedy w nadpisywanej funkcji wywoluje się także standardowa.
  • funkcję wogóle nie zaimplementowane, które musza byc w pełni implementowane przez programiste.


Hook functions są zadeklarowane jako wirtualne, możemy je więc nadpisywac we wlasnych klasąch utworzonych z wykorzystaniem dziedziczenia. 
Zanim zaczniemy przygladac się poszczególnym funkcjom obsługi zdarzeń, musimy jeszcze dowiedziec się jak zaimplementowano obsluge zdarzeń w BeOsię. 

Otóz każde okno i obiekt aplikacji posiadaja własną pętlę obsługi zdarzeń. Na obsluge zdarzeń skladaja się 2 klasy BHandler  i  BLooper  będące w relacji: 




sąma klasą BHandler  implementuje jedynie sposób obsługi komunikatu, nie posiada petli komunikatów. Dopiero klasą BLooper posiada ta pętlę i kolejke komunikatów, a jako ze dziedziczy z BHandler potrafi tez obsługiwac komunikaty. 

Innymi slowy klasą BHandler potrafi jedynie odpowiadac na komunikaty, nie potrafi ich Jednąk wylapywac. Dopiero klasą BLooper potrafi wylapywac komunikaty i dzieki temu ze jest oparta na BHandler potrafi je także obsłużyc. Idac dalej widzimy ze klasy  BWindow  i BApplication  dziedzicza z BLooper  więc posiadaja wlasne pętlę obsługi zdarzeń i kolejki komunikatów. 

Wrócmy teraz do naszego programu. Chcielismy aby nasza aplikacją konczyla swoje dzialanie wraz z zamknieciem okna. W momencie zamkniecia okna wysylany jest komunikat systemówy B_QUIT_REQUESTED , który obsługiwany jest przez funkcję QuitRequested() . Czyli w momencie klikniecia w przycisk zamykajacy uruchamiana jest funkcja obsługi komunikatów QuitRequested(). Jeżeli funkcja ta zwróci wartosc true okno jest zamykane, w przeciwnym wypadku kontynuuje dzialanie. 

Standardowo funkcja ta zwraca wartosc true i okno jest zamykane, możemy ja Jednąk przeciazyc aby wykonywala jeszcze inne operacje np. zamykala aplikację lub pytala czy napewno zamknac okno. 

Funkcja QuitRequested()  dziedziczona jest z klasy  BLooper , więc posiada ja każda klasą wywodzaca się z BLooper  (np. BApplication, BWindow). Aby zamknac cala aplikację wystarczy wyslac komunikatB_QUIT_REQUESTED  do obiektu aplikacji. 

Funkcja sluzaca do wysylania komunikatów do wlasnej petli obsługi zdarzeń jest PostMessąge()  której jedynym argumentem jest stala komunikatu (np. B_QUIT_REQUESTED). 

Podsumowujac aby nasza aplikacją konczyla dzialanie po zamknieciu okna, musimy przeciazyc funkcję QuitReqested()   naszego okna w ten sposób aby wyslala ona do obiektu naszej aplikacji komunikat B_QUIT_REQUESTED  i zwracala wartosc true. 

Na poczatku do klasy naszego okna (plik 
PierwszeOkno.h ) dodajemy prototyp funkcji  QuitRequested()

virtual bool QuitRequested();

Następnie definiujemy nasza funkcję QuitReqested() w pliku PierwszeOkno.cpp

bool PierwszeOkno::QuitRequested() 
{ 
be_app->PostMessąge(B_QUIT_REQUESTED); 
return(true); 
}

Po wprowadzeniu tych zmian nasza aplikacją konczy dzialanie zaraz po zamknieciu okna.  Zmienione pliki w calosci wygladaja teraz tak: 

PierwszeOkno.h: 

//Plik naglówkowy definiujacy klase okna PierwszeOkno.h 
#ifndef _PIERWSZE_OKNO_H_ 
#define _PIERWSZE_OKNO_H_ 

#include<Window.h> 

extern BRect obszarokna; 

class PierwszeOkno : public BWindow 
    { 
    public: 
PierwszeOkno():BWindow(obszarokna,"Pierwsze okno",B_TITLED_WINDOW,0,B_CURRENT_WORKSPACE)
        { 
        } 
    virtual bool QuitRequested(); 
    }; 

#endif

 PierwszeOkno.cpp: 

#include"PierwszeOkno.h" 
#include"PierwszaApp.h" 

BRect obszarokna(20,20,300,200); 

bool PierwszeOkno::QuitRequested() 
    { 
    be_app->PostMessąge(B_QUIT_REQUESTED); 
    return(true); 
    }

Klasy BApplication i BWindow posiadaja po kilkanascie funkcji obsługi komunikatów (hook functions), najważniejsze z nich opisąlem pokrótce ponizej. Pelny opis wraz z argumentami i zwracanymi wartosciami dostepny jest w podreczniku programisty "BeBook", który można sciagnac np. z bebits.com

najważniejsze funkcję obsługi zdarzeń klasy BApplication:
ArgvReceived() funkcja obsluguje komunikat systemówy B_ARGV_RECEIVED; jest wywolywana jedynie gdy zostaly podane jakies parametry linii polecen, przyjmuje dwa argumenty argc - mówiacy o Ilośći argumentów i argv - wskaznik do tablicy zawierajacej te parametry
ReadyToRun() funkcja jest wywolywana tuz przed uruchomieniem petli obsługi zdarzeń
AppActivated() funkcja jest wywolywana gdy aplikacją jest aktywowana lub przestaje byc aktywna
Pulse() funkcja jest wywolywana gdy aplikacją otrzymuje komunikat systemówy B_PULSE. Jest to komunikat wysylany do aplikacji co pewien okreslony czas. Czas ten okreslamy za pomocą funkcji SetPulseRate()
AboutRequested() jest uruchomiana gdy aplikacją otrzyma komunikatB_ABOUT_REQUESTED, w tej funkcji powinny byc zawarte operacje wyswietlajace okienko z informacja o programie

 

najważniejsze funkcję obsługi zdarzeń klasy BWindow:
FrameMoved() funkcja wywolywana gdy zostanie zmienione Położenie okna
FrameResized() funkcja wywolywana gdy zostanie zmieniona wielkosc okna
ScreenChanged() funkcja wywolywana gdy zmieni się rozdzielczosc lub glebia kolorów pulpitu na którym znajduje się okno
WindowActivated() funkcja wywolywana gdy okno zostaje uaktywnione lub przestaje byc aktywne
WorkspaceActivated() funkcja wywolywana gdy zmieni się aktualnie wyswietlany na ekranie pulpit

Program Przykładowy można pobrać stąd [Link].  wróc do indeksu 


   Część 5 - BWindow - najważniejsze funkcje  Ostatnią część kursu dotyczącą klasy BWindow wykorzystamy na poznanie najważniejszych funkcji umożliwiających zarządzanie oknami. Pełny opis wszystkich funkcji klasy BWindow znajduje się oczywiście w BeBook.  IsActive(): 

Składnia funkcji IsActive():
bool IsActive(void) const

 

    Funkcja pozwala określić czy dane okno jest aktywne czy nie zależnie od zwracanej wartości. 

 

Wartości zwracane przez funkcję IsActive():
true okno jest aktywne
false okno nie jest aktywne

 

MoveBy(): 

Składnia funkcji MoveBy():
void MoveBy(float horizontal,float vertical)

 

    Przemieszcza okno, dodając wartość horizontal do aktulnej pozycji x, i watrość vertical do aktualnej pozycji y.

MoveTo(): 

Składnia funkcji MoveTo():
void MoveTo(float x,float y)

 

    Przemieszcza okno tak, aby lewy górny róg obszaru roboczego znajdował się w miejscu oznaczonym współrzędnymi (x,y).

Quit(): 

Składnia funkcji Quit():
virtual void Quit(void)

 

    Funkcja usuwa okno.

ResizeBy(): 

Składnia funkcji ResizeBy():
void ResizeBy(float horizontal, float vertical)

 

    Funkcja zmienia rozmiar okna dodając wartość horizontal do szerokości i wartość vertical do wysokości okna.

ResizeTo(): 

Składnia funkcji ResizeTo():
void ResizeTo(float width, float height)

 

    Funkcja zmienia rozmiar okna ustalając nową szerokość na width, a wysokość na height.

SetFeel(): 

Składnia funkcji SetFeel():
status_t SetFeel(window_feel feel)

 

    Zmienia sposób zachowania okna. 

 

Najważniejsze wartości dla argumentu feel:
B_NORMAL_WINDOW_FEEL okno zachowuje się normalnie
B_FLOATING_ALL_WINDOW_FEEL okno występuje zawsze na wierzchu, na wszystkich pulpitach
B_MODAL_ALL_WINDOW_FEEL okno występuje na zawsze na wierzchu, blokuje dostęp do wszystkich innych na wszystkich pulpitach

Feel(): 

Składnia funkcji funkcji Feel():
window_feel Feel(void) const

 

    Funkcja jako swoją wartość zwraca aktualne flagi określające zachowanie okna.

SetFlags(): 

Składnia funkcji SetFlags():
status_t SetFlags(uint32 flags)

 

    Funkcja SetFlags() pozwala określić opcje okna takie jak np. zakaz zmiany rozmiaru okna. 

 

Najważniejsze wartości dla argumentu flags:
B_NOT_MOVABLE nie pozwala przemieścić okna
B_NOT_CLOsąBLE okno nie posiada przycisku zamknij na pasku tytułowym
B_NOT_ZOOMABLE okno nie posiada przycisku maksymalizuj(zoom) na pasku tytułowym
B_NOT_MINIMIZABLE nie pozwala zminimalizować okna przez podwójne kliknięcie w pasek tytułowy
B_NOT_H_RESIZABLE nie pozwala zmieniać rozmiaru okna w poziomie
B_NOT_V_RESIZABLE nie pozwala zmieniać rozmiaru okna w pionie
B_NOT_RESIZABLE nie pozwala zmieniać rozmiaru okna w żadnym kierunku

Flags(): 

Składnia funkcji funkcji Flags():
uint32 Flags(void) const

 

    Funkcja jako swoją wartość zwraca aktualnie ustawione opcje dla danego okna (te które są ustawiane np. w konstruktorze w parametrze flags).

SetLook(): 

Składnia funkcji SetLook():
status_t SetLook(window_look look)

 

    Pozwala zmienić wygląd okna. 

 

    Najważniejsze wartości argumentu look: 

B_DOCUMENT_WINDOW_LOOK

     - duży pasek tytułu, grube obramowanie, duży kwadrat do zmiany rozmiaru okna w prawym dolnym rogu: 

 

B_TITLED_WINDOW_LOOK

     - to samo co wyżej ale kwadrat do zmiany rozmiaru został zastąpiony wyznaczeniem części obramowania okna: 

 

B_FLOATING_WINDOW_LOOK

     - mały pasek tytułu, wąskie obramowanie, prawy dolny róg obramowania służy do zmiany rozmiaru okna: 

 

B_MODAL_WINDOW_LOOK

     - brak pasku tytułowego, grube obramowanie, brak kontrolki zmiany rozmiaru okna: 

 

B_BORDERED_WINDOW_LOOK

     - brak paska tyułowego, obramowanie, brak kontrolki zmiany rozmiaru okna: 

 

B_NO_BORDER_WINDOW_LOOK

     - brak wszelkich ozdób okna

Look(): 

Składnia funkcji Look():
window_look Look(void) const

 

    Funkcja jako swoją wartość zwraca flagę określającą wygląd okna, są to te same flagi co w argumencie look konstruktora okna.

SetPulseRate(): 

Składnia funkcji SetPulseRate():
void SetPulseRate(bigtime_t microseconds)

 

    Określa co jaki czas do aplikacji ma być wysyłany komunikat systemowy B_PULSE, komunikat ten obsługiwany jest przez funkcję Pulse(), którą możemy przeciążyć aby wykonywała dla nas jakieś operacje co określony czas. 

 

    Ustawienie wartości 0, wyłącza wysyłanie komunikatu B_PULSE dla danego okna i wszystkich należących do niego klas widoku (o klasach widoku napiszę w następnej części kursu).

PulseRate(): 

Składnia funkcji PulseRate():
bigtime_t PulseRate(void)

 

    Zwraca aktualnie ustawioną wartość mikrosekund pomiędzy kolejnymi wysyłanymi komunikatami 

B_PULSE

    .

SetSizeLimits(): 

Składnia funkcji SetSizeLimits():
void SetSizeLimits(float minWidth, float maxWidth, float minHeight, float maxHeight)

 

    Funkcja pozwala ustawić limity ograniczające możliwość zmiany wielkości okna. 

 

Argumenty funkcji SetSizeLimits():
minWidth minimalna szerokość okna
maxWidth maksymalna szerokość okna
minHeight minimalna wysokość okna
maxHeight maksymalna wysokość okna

GetSizeLimits(): 

Składnia funkcji GetSizeLimits():
void GetSizeLimits(float *minWidth, float *maxWidth, float *minHeight, float *maxHeight)

 

    Funkcja zapisuje aktualne limity pod zmienne, których wskaźniki podane zostały jako argumenty funkcji.

SetZoomLimits(): 

Składnia funkcji SetZoomLimits():
void SetZoomLimits(float maxWidth, float maxHeight)

 

    Funkcja SetZoomLimits() ustawia limity ograniczające możliwość powiększenia okna za pomocą przycisku Zoom. 

 

Argumenty funkcji SetZoomLimits():
maxWidth maksymalna szerokość okna
maxHeight maksymalna wysokość okna

 

    Oprócz funkcji SetZoomLimits() limit na rozmiar okna nakłada także funkcja SetSizeLimits() należy więc pamiętać że wybierany jest ten bardziej restrykcyjny.

SetTitle(): 

Składnia funkcji SetTitle():
void SetTitle(const char * newTitle)

 

    Zmienia nazwę okna wyświetlaną na pasku tytułowym, a także nazwę wątku okna.

Title(): 

Składnia funkcji Title():
const char *Title() const

 

    Funkcja zwraca wskaźnik do łańcucha znaków reprezentującego tytuł okna. łańcuch ten jest zakończony znakiem null i należy do okna, więc jeśli potrzebny jest na dłużej należy przekopiować go do własnego bufora.

SetType(): 

Składnia funkcji SetType():
status_t SetType(window_type type)

 

    Typ okna zwykle ustawiany jest w argumencie type konstruktora okna. Funkcja SetType() pozwala zmienić typ okna dla już istniejącego okna. 

 

Najważniejsze wartości dla argumentu type
B_TITLED_WINDOW okno wyglądające jak B_TITLED_WINDOW_LOOK i zachowujące się normalnie (B_NORMAL_WINDOW_FEEL)
B_DOCUMENT_WINDOW okno wyglądające jak B_DOCUMENT_WINDOW_LOOK i zachowujące się normalnie (B_NORMAL_WINDOW_FEEL)
B_MODAL_WINDOW okno wyglądające jak B_MODAL_WINDOW_LOOK i blokujące dostęp do wszystkich innych okien aplikacji (B_MODAL_APP_WINDOW_FEEL)
B_BORDERED_WINDOW okno wyglądające jak B_BORDERED_WINDOW_LOOK i zachowujące się normalnie
B_UNTYPED_WINDOW okno o nieznanym typie

 

Type() 

Składnia funkcji Type():
window_type Type(void) const

 

    Funkcja jako swoją wartość zwraca typ okna.

SetWorkspaces(): 

Składnia funkcji SetWorkspaces():
void SetWorkspaces(uint32 workspaces)

 

    Umieszcza okno na określonym pulpicie.

Workspaces(): 

Składnia funkcji Workspaces():
uint32 Workspaces(void) const

 

    Funkcja zwraca numer pulpitu, na którym znajduje się okno.

Show(): 

Składnia funkcji Show():
virtual void Show(void)

 

    Funkcja czyni okno widocznym i aktywnym. Jeżeli jest ot pierwsze wywołanie Show() dla tego okna uruchamiana jest też pętla obsługi zdarzeń.

Hide(): 

Składnia funkcji Hide():
virtual void Hide(void)

 

    Czyni okno niewidocznym, usuwa je także z listy okien deskbara. Jeżeli wywołamy Hide() kilka razy, konieczne będzie również kilkukrotne wywołanie Show(), aby okno się pojawiło.

Minimize(): 

Składnia funkcji Minimize():
virtual void Minimize(bool minimize)

  

    Ukrywa lub pokazuje okno zależnie od warotści argumentu minimize. Funkcja Minimize() od Hide() różni się tym, że nazwa okna ukrytego za pomocą Minimize() nie jest usuwana z listy okien deskbara. 

 

Możliwe wartości argumentu minimize:
true okno zostanie zminimalizowane
false okno zostanie uwidocznione na ekranie

IsHidden(): 

Składnia funkcji IsHidden():
bool IsHidden(void) const

 

    Zwraca wartość true, jeżeli okno jest ukryte.

IsMinimized(): 

Składnia funkcji IsMinimized():
bool IsMinimized(void) const

 

    Zwraca wartość true jeżeli okno jest zminimalizowane.

wróc do indeksu 


  Część 6 - Klasa BView:  Skoro potrafimy już tworzyć okna, miło byłoby coś w nich umieścić, narysować itp. Funkcje te udostępnia nam klasa widoku BView i jej pochodne. Sama klasa BView jest chyba najbardziej rozbudowaną klasą w BeOSie. Od klasy tej pochodzą bezpośrednio lub pośrednio wszystkie klasy, które rysują/wyświetlają jakąkolwiek grafikę wewnątrz okien np. przyciski, pola edycyjne itd.  Zwykle okna zawierają wiele różnych klas widoków, które tworzą coś na kształt drzewiastej struktury. Szczyt tej struktury stanowi tzw. Top View. Widok standardowo znajdujący się w oknie, służący jedynie jako podstawa, do której dodajemy następne obiekty widoku.  Aby dodać obiekt widoku do okna, lub innego obiektu widoku korzystamy z funkcji AddChild(). Funkcję tą wywołujemy z obiektu, do którego chcemy dodać obiekt widoku.  Zanim dodamy obiekt widoku do okna (bądź innego widoku) musimy go najpierw stworzyć, konstruktor klasy BView wygląda następująco: 

BView(BRect frame, const char *name,uint32 resizingMode, uint32 flags);

 

Opis argumentów konstruktora klasy BView:
frame obiekt BRect określający obszar który zajmie nasz obiekt widoku (o klasie BRect pisałem więcej w 3 części kursu)
name nazwa dla naszej klasy widoku, która może później zostać przez nas wykorzystana jako alternatywny sposób odwoływania się do naszego obiektu (funkcja FindView()), może być ustalone na NULL
resizingMode flaga określająca zachowanie naszego obiektu, na zmianę rozmiaru właściciela. Najważniejsze wartości to: 
B_FOLLOW_LEFT margines między lewą krawędzią obiektu widoku, a krawędzią właściciela nie zmieni się
B_FOLLOW_RIGHT margines między prawą krawędzią obiektu widoku, a krawędzią właściciela nie zmieni się
B_FOLLOW_LEFT_RIGHT margines między lewą krawędzią obiektu widoku, a krawędzią właściciela nie zmieni się, a także margines między prawą krawędzią obiektu widoku, a krawędzią właściciela nie ulegnie zmianie
B_FOLLOW_H_CENTER w trakcie zmiany wielkości właściciela, obiekt pozostanie w środku (flaga ustawia zachowanie jedynie dla kierunku poziomego)
B_FOLLOW_TOP odległość między górną krawędzią obiektu widoku, a górną krawędzią właściciela nie zmieni się
B_FOLLOW_BOTTOM odległość między dolną krawędzią obiektu widoku, a dolną krawędzią właściciela nie zmieni się
B_FOLLOW_TOP_BOTTOM obiekt widoku zostanie rozciągnięty tak aby odległości między górną krawędzią obiektu widoku, a krawędzią właściciela a także między dolną krawędzią obiektu widoku, a dolną krawędzią właściciela nie zmieniła się
B_FOLLOW_V_CENTER w trakcie zmiany wielkości właściciela, obiekt pozostanie w środku (flaga ustawia zachowanie jedynie dla kierunku pionowego), obiekt nie będzie rozciągany
B_FOLLOW_ALL_SIDES to samo co B_FOLLOW_LEFT_RIGHT i B_FOLLOW_TOP_BOTTOM
B_FOLLOW_NONE to samo co B_FOLLOW_LEFT i B_FOLLOW_TOP
flags określa jakie komunikaty będzie otrzymywał obiekt BView. Wartość jest kombinacją makr: 
B_WILL_DRAW oznacza, że BView będzie coś rysowało, ustawienie tej flagi powoduje, że obiekt widoku będzie otrzymywał komunkat mówiący że należy przerysować zawartość, obsługiwany przez funkcję Draw()
B_PULSE_NEEDED oznacza, że BView będzie otrzymywało komunikat B_PULSE, obsługiwany przez funkcję Pulse()
B_FRAME_EVENTS oznacza, że BView bedzie otrzymywało komunikaty dotyczące zmiany rozmiaru/położenia, obsługiwane przez funkcje FrameResized(), FrameMoved()
B_FULL_UPDATE_ON_RESIZE oznacza że całe wnętrze obiektu BView będzie aktualizowane, po zmianie rozmiaru
B_NAVIGABLE umożliwia zmianę ogniska klawiatury na ten obiekt za pomocą klawisza Tab
B_NAVIGABLE_JUMP umożliwia ustawianie grup obiektów B_NAVIGABLE, grupę możemy zmienić za pomocą Control+Tab. Grupę tworzymy nadając obiektowi wyższego poziomu flagę B_NAVIGABLE_JUMP, a obiektom podrzędnym B_NAVIGABLE
B_SUBPIXEL_PRECISE wyłącza zaokrąglanie współrzędnych do całości
Jeżeli nie chcemy ustawić żadnej flagi możemy ustawić wartość argumentu flags na NULL.

Dodawanie obiektu BView: Jak już wcześniej wspomniałem aby dodać obiekt widoku do okna lub innego obiektu widoku używamy funkcji AddChild() o następującej składni:

virtual void AddChild(BView aview);

Jedynym argumentem funkcji jest nazwa obiektu BView, który chcemy dołączyć, a samą funkcję AddChild() wywołujemy z obiektu, do którego chcemy dodać nowy obiekt BView. Na przyszłość należy także pamiętać, że wszystkie kontrolki w BeOSie (np. przyciski) pochodzą od klasy BView, więc zwykle do okna są dodawane za pomocą funkcji AddChild().  Usuwanie obiektu BView:  Zwykle cała drzewiasta struktura obiektów BView jest uwalniana przy usuwaniu okna i nic nie musimy robić, jeżeli chcemy sami usunąć obiekt BView to najpierw należy "odłączyć" go od okna, za pomocą funkcji RemoveChild() o składni: 

virtual bool RemoveChild(BView aView);

Gdzie aView jest nazwą obiektu który odłączamy od okna/innego obiektu BView. Następnie standardowo korzystamy z operatora delete.  Program przykładowy ObiektWidoku:  Podobnie jak z klasami aplikacji i okna, tworząc obiekt widoku nie korzystamy wprost z klasy BView, ale tworzymy klasę opartą na niej. Naszą klasę nazwiemy poprostu Klasa_widoku: 

class Klasą_widoku : public BView 
{ 
public : 
Klasą_widoku(); 
virtual void Draw(BRect); 
};

Konstruktor naszej klasy będzie wywoływał oryginalny konstruktor klasy BView określający rozmiar naszego przyszłego widoku na 200,80 a jego prawy górny róg będzie znajdował się w punkcie (20,20). Nazwę za pomocą, której będziemy mogli wyszukać obiekt widoku ustawimy na "widok", nasz obiekt będzie także zmieniał swoją wielkość zgodnie ze zmianą okna, będzie także dostawał komunikaty nakazujące aktualizację wyświetlanej przez niego grafiki za pomocą funkcji Draw(): 

BRect obszarwidoku(20,20,200,80); 

Klasą_widoku::Klasą_widoku():BView(obszarwidoku, "widok",B_FOLLOW_ALL,B_WILL_DRAW)
{ 
}

Drugą funkcją zadeklarowaną w naszej klasie jest funkcja Draw(). Jak przed chwilą wspomniałem funkcja ta jest wykonywana zawsze gdy nasz obiekt widoku otrzyma komunikat nakazujący przerysowanie jego zawartości. W naszym przypadku funkcja ta jedynie przesuwa pisak do pozycji (20,20) (MoveToPen(20,20)), a następnie wypisuje tekst "To jest tekst wyświetlany" (DrawString("To jest tekst wyświetlany");), po czym pisak przesuwany jest do pozycji (20,40) i wypisywany jest tekst "przez obiekt BView": 

void Klasą_widoku::Draw(BRect) 
{ 
MovePenTo(20,20);//przesunięcie pisaka do pozycji 20,20 
DrawString("To jest tekst wyswietlany");//wypisanie tekstu 
MovePenTo(20,40);//przesunięcie pisaka do pozycji 20,40 
DrawString("przez obiekt BView.");//wypisanie tekstu 
}

Sam wskaźnik do obiektu BView zawarty jest w klasie okna, a obiekt tworzony i dołączany do okna jest w konstruktorze klasy okna: 

 
class Klasą_Okna : public BWindow 
{ 
public : 
Klasą_Okna(); 
virtual bool QuitRequested(); 
Klasą_widoku * Widok; 
}; 

Klasą_Okna::Klasą_Okna():BWindow (obszarokna,"Okno",B_TITLED_WINDOW,0,B_CURRENT_WORKSPACE)
{ 
Widok = new Klasą_widoku; 
AddChild(Widok); 
}

Cały kod źródłowy wygląda następująco: 

Plik Widok.h:

//plik nagłówkowy definiujący klasę widoku 
#ifndef _WIDOK_H_ 
#define _WIDOK_H_ 

#include<View.h> 

extern BRect obszarwidoku; 

class Klasą_widoku : public BView 
    { 
    public: 
    Klasą_widoku(); 
    virtual void Draw(BRect); 
    }; 
#endif

Plik Widok.cpp:

#include"Widok.h" 

BRect obszarwidoku(0,0,200,80); 

Klasą_widoku::Klasą_widoku():BView (obszarwidoku,"widok",B_FOLLOW_ALL,B_WILL_DRAW) 
    { 
    } 

void Klasą_widoku::Draw(BRect) 
    { 
    MovePenTo(20,20); 
    DrawString("To jest tekst wyswietlany"); 
    MovePenTo(20,40); 
    DrawString("przez obiekt BView."); 
    }

Plik Okno.h:

//Plik nagłówkowy definiujący klasę okna 
#ifndef _OKNO_H_ 
#define _OKNO_H_ 

#include<Window.h> 
#include"Widok.h" 

extern BRect obszarokna; 

class Klasą_Okna : public BWindow 
    { 
    public : 
    Klasą_Okna(); 
    virtual bool QuitRequested(); 

    Klasą_widoku * Widok; 
    }; 

#endif​

Plik Okno.cpp:

/* 
        Plik źródłowy PierwszeOkno.cpp zawierający definicje funkcji 
*/ 
#include"aplikacją.h" 
#include"Okno.h" 

BRect obszarokna(20,20,300,200); 

bool Klasą_Okna::QuitRequested() 
    { 
    be_app->PostMessąge(B_QUIT_REQUESTED); 
    return(true); 
    } 

Klasą_Okna::Klasą_Okna():BWindow (obszarokna,"Okno",B_TITLED_WINDOW,0,B_CURRENT_WORKSPACE)
    { 
    Widok = new Klasą_widoku; 
    AddChild(Widok); 
    }​

Plik aplikacją.h:

//Plik nagłówkowy definiujący klasę aplikacji 
#ifndef _aplikacją_H_ 
#define _aplikacją_H_ 

#include <Application.h> 
#include"Okno.h" 

class aplikacją : public BApplication 
    { 
    public: 
    aplikacją(); 

    Klasą_Okna * POkno; 
    }; 
#endif​

Plik aplikacją.cpp:

#include"aplikacją.h" 

int main() 
    { 
    new aplikacją(); 
    be_app->Run(); 
    delete be_app; 
    } 

aplikacją::aplikacją():BApplication ("application/obiektwidoku") 
    { 
    POkno = new Klasą_Okna; 
    POkno->Show(); 
    POkno->Widok->Show(); 
    }​

Okno programu przykładowego powinno wyglądać następująco: 

Rys.1 Program przykładowy Obiekt Widoku 1.0.

Program przykładowy można ściągnąć stąd [Link].  wróc do indeksu 


  Część 7 - BView - podstawowe funkcje rysujące  Klasa BView posiada ogromną liczbę funkcji rysujących, od najprostszych jak rysowanie linii, do bardziej skomplikowanych pozwalających np. kopiować bitmapy. Pozycja, określanie współrzędnych:  Aby móc cokolwiek narysować na powierzchni potrzebny jest jakiś sposób na jednoznaczne określenie współrzędnych. W BeOSie najczęściej wykorzystywane są do tego dwie klasy - BPoint i BRect.  Klasa BPoint:  Klasa BPoint jednoznacznie określa położenie punktu na ekranie, a jej konstruktor wygląda następująco: 

inline BPoint(float x,float y);

czyli, aby stworzyć obiekt BPoint wskazujący na pozycję (10,10) wystarczy napiasać: 

BPoint punkt(10,10);

aby zmienić współrzędne, na które wskazuje obiekt BPoint używamy funkcję Set() np.: 

punkt.Set(30,40);

aby obiekt wskazywał na współrzędną (30,40). Klasa BRect:  Klasę BRect dokładniej omówiłem w trzeciej części kursu [Link].  Podstawowe funkcje rysujące:  Rysowanie Linii:  Do rysowania linii służy funkcja StrokeLine() o składni: 

void StrokeLine(BPoint start, BPoint end, pattern aPattern = B_SOLID_HIGH); 
void StrokeLine(BPoint end, pattern aPattern = B_SOLID_HIGH);

 

Opis argumentów funkcji StrokeLine():
start obiekt BPoint określający współrzędne początku linii
end obiekt BPoint określający współrzędne końca linii
aPattern określa rodzaj linii, jeżeli pominiemy ten argument zostanie ustawiony na ciągłą o kolorze high

Jeżeli nie podamy punktu startowego linia zostanie narysowana od aktualnej pozycji pisaka.  Np. aby narysować linię od punktu (12,12) do (49, 56): 

BPoint s(12,12); 
BPoint k(49,56); 
StrokeLine(s,k);

Np. aby narysować linię od aktualnej pozycji pisaka do (100,200): 

BPoint koniec(100,200); 
StrokeLine(koniec);

Rysowanie prostokąta:  Aby narysować prostokąt należy użyć funkcji StrokeRect() o składni: 

void StrokeRect(BRect rect, pattern aPattern = B_SOLID_HIGH);

 

Opis argumentów funkcji StrokeRect():
rect obiekt BRect określający prostokąt do narysowania
aPattern rodzaj linii/obramowania, jeżeli nie ustawione to ciągła

Np. aby narysować prostokąt o lewym górnym rogu w punkcie 15,20, szerokości 200 i wysokości 50: 

BRect prostok(15,20,200,50); 
StrokeRect(prostok);

Rysowanie wypełnionego prostokąta:  Do rysowania wypełnionego prostokąta służy funkcja FillRect() o składni:  

void FillRect(BRect rect, pattern aPattern = B_SOLID_HIGH);
Opis argumentów funkcji FillRect():
rect obiekt BRect określający prostokąt do narysowania
aPattern wzór według którego zostanie narysowany wypełniony prostokąt, domyślnie kolor high

Np. aby narysować wypełniony prostokąt o lewym górnym rogu w punkcie 15,20, szerokości 200 i wysokości 50: 

BRect prostok(15,20,200,50); 
FillRect(prostok);

Rysowanie prostokąta z zaokrąglonymi kątami:  Używamy funkcję StrokeRoundRect() o składni:  

void StrokeRoundRect(BRect rect, float xRadius, float yRadius, pattern aPattern = B_SOLID_HIGH);
Opis argumentów funkcji StrokeRoundRect():
rect obiekt BRect określający prostokąt do narysowania
xRadius promień zaokrąglenia w kierunku x
yRadius promień zaokrąglenia w kierunku y
aPattern wzór według którego zostanie narysowany wypełniony prostokąt, domyślnie kolor high

Rysowanie wypełnionego prostokąta z zaokrąglonymi kątami:  Używamy funkcję FillRoundRect() o składni: 

void FillRoundRect(BRect rect, float xRadius, float yRadius, pattern aPattern = B_SOLID_HIGH);

 

Opis argumentów funkcji FillRoundRect():
rect obiekt BRect określający prostokąt do narysowania
xRadius promień zaokrąglenia w kierunku x
yRadius promień zaokrąglenia w kierunku y
aPattern wzór według którego zostanie narysowany wypełniony prostokąt, domyślnie kolor high

Rysowanie trójkąta: Aby narysować trójkąt używamy funkcję StrokeTriangle() o składni:   

void StrokeTriangle(BPoint firstPoint, BPoint secondPoint, BPoint thirdPoint, pattern aPattern = B_SOLID_HIGH);
Opis argumentów funkcji StrokeTriangle():
firstPoint, secondPoint, thirdPoint współrzędne wierzchołków trójkąta
aPattern wzór według którego zostanie narysowany trójkąt, domyślnie kolor high

Rysowanie wypełnionego trójkąta:  Używamy funkcję FillTriangle() o składni: 

void FillTriangle(BPoint firstPoint, BPoint secondPoint, BPoint thirdPoint, pattern aPattern = B_SOLID_HIGH);
Opis argumentów funkcji StrokeTriangle():
firstPoint, secondPoint, thirdPoint współrzędne wierzchołków trójkąta
aPattern wzór według którego zostanie narysowany trójkąt, domyślnie kolor high

Rysowanie elipsy: Używamy funkcję StrokeEllipse() o składni: 

void StrokeEllipse(BRect rect, pattern aPattern = B_SOLID_HIGH); 
void StrokeEllipse(BPoint center, float xRadius, float yRadius,pattern aPattern = B_SOLID_HIGH);
Opis argumentów funkcji StrokeEllipse():
rect prostokąt w którym zawarta będzie elipsa
center środek elipsy
xRadius promień w poziomie
yRadius promień w pionie
aPattern wzór według którego zostanie narysowana elipsa, domyślnie kolor high

Np. aby narysować elipsę która będzie mieściła się w prostokącie o współrzędnych (10,10), szerokości 100, wysokości 50: 

BRect pr(10,10, 100, 50);
StrokeEllipse(pr);

Np. aby narysować elipsę, o środku w punkcie 100,100, promieniu poziomym 100 i promieniu pionowym 75: 

BPoint srodek(100,100); 
StrokeEllipse(srodek,100,75);

Rysowanie wypełnionej elipsy: Używamy funkcję FillEllipse() o składni:  

void FillEllipse(BRect rect, pattern aPattern = B_SOLID_HIGH); 
void FillEllipse(BPoint center, float xRadius, float yRadius, pattern aPattern = B_SOLID_HIGH);
 
Opis argumentów funkcji FillEllipse():
rect prostokąt w którym zawarta będzie elipsa
center środek elipsy
xRadius promień w poziomie
yRadius promień w pionie
aPattern wzór według którego zostanie narysowana elipsa, domyślnie kolor high

Np. aby narysować wypełnioną elipsę która będzie mieściła się w prostokącie o współrzędnych (10,10), szerokości 100, wysokości 50: 

BRect pr(10,10, 100, 50); 
FillEllipse(pr);

Np. aby narysować wypełnioną elipsę, o środku w punkcie 100,100, promieniu poziomym 100 i promieniu pionowym 75: 

BPoint srodek(100,100); 
FillEllipse(srodek,100,75);

Rysowanie wycinka elipsy:  Używamy funkcję StrokeArc() o składni: 

void StrokeArc(BRect rect, float angle, float span, pattern aPattern = B_SOLID_HIGH); 
void StrokeArc(BPoint center, float xRadius, float yRadius, float angle, float span,pattern aPattern = B_SOLID_HIGH);
Opis argumentów funkcji StrokeArc():
rect prostokąt w którym zawarta będzie elipsa
center środek elipsy
xRadius promień w poziomie
yRadius promień w pionie
angle kąt pomiędzy osią x a początkiem rysowanego wycinka elipsy
span ilość stopni zgodnie ze wskazówkami zegara, określająca wielkość wycinka elipsy
aPattern wzór według którego zostanie narysowany wycinek elipsy, domyślnie kolor high

Rysowanie wypełnionego wycinka elipsy: Używamy funkcję FillArc() o składni:    

void FillArc(BRect rect, float angle, float span, pattern aPattern = B_SOLID_HIGH); 
void FillArc(BPoint center, float xRadius, float yRadius, float angle, float span, pattern aPattern = B_SOLID_HIGH);
Opis argumentów funkcji FillArc():
rect prostokąt w którym zawarta będzie elipsa
center środek elipsy
xRadius promień w poziomie
yRadius promień w pionie
angle kąt pomiędzy osią x a początkiem rysowanego wycinka elipsy
span ilość stopni zgodnie ze wskazówkami zegara, określająca wielkość wycinka elipsy
aPattern wzór według którego zostanie narysowany wycinek elipsy, domyślnie kolor high

Program przykładowy - Funkcje Rysujące: Program przyk?adowy prezentuje, co 1500000 mikrosekund inn? funkcj? rysuj?c?, zaczynaj?c od StrokeRect(), a ko?cz?c na FillArc().  Program przykładowy prezentuje, co 1500000 mikrosekund inną funkcję rysującą, zaczynając od StrokeRect(), a kończąc na FillArc().  Program korzysta z komunikatu systemowego B_PULSE, aby zmieniać wartość zmiennej licznik określającej, jaka figura ma być narysowana oraz z funkcji Invalidate() nakazującej obiektowi BView przerysować swoją zawartość. Funkcją wywoływaną, gdy obiekt musi przerysować swoją zawartość jest funkcja Draw(), która na podstawie wartości zmiennej licznik rysuje odpowiednią figurę.  A oto pełny kod źródłowy programu przykładowego: 

Plik Widok.h: 

 

//plik nagłówkowy definiujący klasę widoku 
#ifndef _WIDOK_H_ 
#define _WIDOK_H_ 

#include<View.h> 

extern BRect obszarwidoku; 

class Klasą_widoku : public BView 
    { 
    public : 
        Klasą_widoku(); 
        virtual void Draw(BRect); 
        virtual void Pulse(); 

        int licznik; 
    }; 
#endif
​

Plik Widok.cpp: 

#include"Widok.h" 

BRect obszarwidoku(0,0,400,400); 

Klasą_widoku::Klasą_widoku():BView (obszarwidoku,"widok",B_FOLLOW_ALL,B_WILL_DRAW|B_PULSE_NEEDED)
    { 
    licznik=0; 
    } 

void Klasą_widoku::Draw(BRect) 
    { 
    BRect kw(40,40,320,220); 
    BPoint ws(40,280); 
    BPoint w1(180,40); 
    BPoint w2(40,260); 
    BPoint w3(320,260); 

    switch(licznik) 
        { 
        case 0: 
            StrokeRect(kw); 
            DrawString("Funkcja StrokeRect()",ws); 
            break; 
        case 1: 
            FillRect(kw); 
            DrawString("Funkcja FillRect()",ws); 
            break; 
        case 2: 
            StrokeRoundRect(kw,10,10); 
            DrawString("Funkcja StrokeRoundRect()",ws); 
            break; 
        case 3: 
            FillRoundRect(kw,10,10); 
            DrawString("Funkcja FillRoundRect()",ws); 
            break; 
        case 4: 
            StrokeTriangle(w1,w2,w3); 
            DrawString("Funkcja StrokeTriangle()",ws); 
            break; 
        case 5: 
            FillTriangle(w1,w2,w3); 
            DrawString("Funkcja FillTriangle()",ws); 
            break; 
        case 6: 
            StrokeEllipse(kw); 
            DrawString("Funkcja StrokeEllipse()",ws); 
            break; 
        case 7: 
            FillEllipse(kw); 
            DrawString("Funkcja FillEllipse()",ws); 
            break; 
        case 8: 
            StrokeArc(kw,0,179); 
            DrawString("Funkcja StrokeArc()",ws); 
            break; 
        case 9: 
            FillArc(kw,0,179); 
            DrawString("Funkcja FillArc()",ws); 
            break; 
        } 

    DrawString("Program przykładowy ze strony And3mD Haiku Dev.",BPoint(45,340)); 
    DrawString("www.haikudev.prv.pl",BPoint(125,360)); 
    } 

void Klasą_widoku::Pulse() 
    { 
    licznik=licznik+1; 
    if (licznik>9) licznik=0; 
    Invalidatę(); 
    }​

 

Plik Okno.h:  

//Plik nagłówkowy definiujący klasę okna 
#ifndef _OKNO_H_ 
#define _OKNO_H_ 

#include<Window.h> 
#include"Widok.h" 

extern BRect obszarokna; 

class Klasą_Okna : public BWindow 
    { 
    public : 
        Klasą_Okna(); 
        virtual bool QuitRequested(); 

        Klasą_widoku * Widok; 
    }; 
#endif​

 Plik Okno.cpp: 

/* 
        Plik źródłowy Okno.cpp zawierający definicje funkcji 
*/ 
#include"aplikacją.h" 
#include"Okno.h" 

BRect obszarokna(30,30,400,400); 

bool Klasą_Okna::QuitRequested() 
    { 
    be_app->PostMessąge(B_QUIT_REQUESTED); 
    return(true); 
    } 

Klasą_Okna::Klasą_Okna():BWindow (obszarokna,"Podstawowe funkcję rysujace BView",B_TITLED_WINDOW,B_NOT_RESIZABLE,B_CURRENT_WORKSPACE)
    { 
    SetPulseRate(1500000); 
    Widok = new Klasą_widoku; 
    AddChild(Widok); 
    }​

Plik Aplikacja.h: 

 

//Plik nagłówkowy definiujący klasę aplikacji 
#ifndef _aplikacją_H_ 
#define _aplikacją_H_ 

#include <Application.h> 
#include"Okno.h" 

class aplikacją : public BApplication 
    { 
    public : 
        aplikacją(); 

        Klasą_Okna * POkno; 
    }; 
#endif​

 Plik Aplikacja.cpp: 

#include"aplikacją.h" 

int main() 
    { 
    new aplikacją(); 
    be_app->Run(); 
    delete be_app; 
    } 

aplikacją::aplikacją():BApplication("application/obiektwidoku") 
    { 
    POkno = new Klasą_Okna; 
    POkno->Show(); 
    POkno->Widok->Show(); 
    }​

  Okno programu przykładowego powinno wyglądać następująco: 

Rys.1 Program przykładowy Funkcje Rysujące 1.0.

Program przykładowy można ściągnąć stąd [Link].  wróc do indeksu 


   Część 8 - BView - kolory  Zanim zapoznamy się z funkcjami umożliwiającymi zmianę koloru, powinniśmy dowiedzieć się jak zapisywana i przechowywana jest barwa w BeOSie.  Barwy w BeOSie zapisywane są według standardu RGBA, i przechowywane w strukturze rgb_color o składni: 

typedef struct { 
uint8 red; 
uint8 green; 
uint8 blue; 
uint8 alpha; 
} rgb_color

Pola red, green, blue reprezentują nasycenie odpowiednio czerwonego, zielonego i niebieskiego składnika koloru, dodatkowo wartość alpha określa przeźroczystość (0 - totalnie przeźroczyste, 255 - zupełny brak przeroczystości). Przykładowo aby zapisać barwę zieloną bez przeźroczystości wystarczy napisać: 

rgb_color barwa_zielona = {0,255,0,255}

Sam zapis barwy w strukturze rgb_color nie pozwala nam wykorzystać jej np. w funkcjach rysujących.  Aby móc wykorzystać jakąkolwiek barwę należy przypisać ją jednemu z dwóch kolorów zwanych high i low (standardowo kolor high ustawiony jest na czarny, a kolor low na biały).  Barwę przypisujemy do koloru high za pomocą funkcji SetHighColor(), a do koloru low za pomocą funkcji SetLowColor(). Funkcje te mają odpowiednio składnię: 

 
virtual void SetHighColor(rgb_color color); 
inline void SetHighColor(uchar red, uchar green, uchar blue, uchar alpha = 255); 

virtual void SetLowColor(rgb_color color); 
inline void SetLowColor(uchar red, uchar green, uchar blue, uchar alpha = 255);

gdzie argument color oznacza barwę zapisaną w strukturze rgb_color, opcjonalnie możemy użyć wersji z 4 argumentami oznaczającymi kolejno nasycenie składnika czerwonego (red), zielonego (green), niebieskiego (blue) barwy i poziom przeźroczystości (alpha).  Np.:  aby ustawić barwę zieloną dla koloru high wystarczy: 

rgb_color zielony = {0,255,0,255} 
SetHighColor(zielony);

Barwę przypisaną do kolorów high i low możemy odczytać za pomocą funkcji HighColor() i LowColor() o składni: 

rgb_color HighColor(void); 
rgb_color LowColor(void);

Przykładowo, aby odczytać barwę koloru low wystarczy napisać: 

rgb_color barwa; 
barwa = LowColor();

OK, potrafimy już przypisać barwę do koloru high, czy low, ale jak je wykorzystać w funkcjach rysujących? Nic prostszego, ostatnim argumentem prawie każdej (jeżeli nie każdej ;) funkcji rysującej jest argument aPattern np. w funkcji rysującej linie występuje jako trzeci:  

void StrokeLine(BPoint start, BPoint end, pattern aPattern = B_SOLID_HIGH);

aPattern daje naprawdę duże możliwości, dzięki niemu w funkcjach rysujących można wykorzystywać wcześniej stworzone własne wzory. Zwykle jednak najczęściej korzysta się z jednego z trzech predefiniowanych makr: 

  • B_SOLID_HIGH - oznacza że użyty zostanie kolor high
  • B_SOLID_LOW - oznacza że użyty zostanie kolor low
  • B_MIXED_COLORS - oznacza że zostanie użyty wzór złożony z barw high i low przypominający efekt dithering.

Jeżeli chcemy dla przykładu, narysować linię kolorem low wystarczy argument aPattern ustawić na B_SOLID_LOW: 

StrokeLine(BPoint(0,0),BPoint(100,100),B_SOLID_LOW);

Jeżeli chcemy rysować kolorem high sytuacja jest jeszcze prostsza, ponieważ kolor ten standardowo ustawiony jest jako domyślny, więc możemy w ogóle pominąć argument aPattren: 

 
StrokeLine(BPoint(0,0),BPoint(100,100),B_SOLID_HIGH); 
StrokeLine(BPoint(0,0),BPoint(100,100));

Dwa powyższe wywołania funkcji StrokeLine() rysują dokładnie tą samą linię, za pomocą koloru high.UWAGA!  Jeżeli wykorzystujemy kolor low do rysowania należy pamiętać, że jest on także wykorzystywany do wygładzania krawędzi czcionek, czyli zanim zaczniemy wypisywać jakiś tekst należy jego barwę ustawić na barwę tła.  Kolor tła obiektu BView:  Każdy obiekt BView oprócz kolorów high i low posiada także kolor tła. Standardowo kolor ten ustawiony jest na biały.  Zmianę koloru tła umożliwia nam funkcja SetViewColor() o składni: 

virtual void SetViewColor(rgb_color color); 
inline void SetViewColor(uchar red, uchar green, uchar blue, uchar alpha = 255);

Znaczenie wszystkich argumentów jest identyczne jak w przypadku funkcji SetHighColor() i SetLowColor().  Analogicznie jak w przypadku kolorów high i low, możemy pobrać aktualine ustawioną barwę tła. Służy do tego funkcja ViewColor() np.: 

rgb_color tlo; 
tlo = ViewColor();

Program przykładowy:  Program przykładowy do tej części kursu, rysuje trzy słupki. Pierwszy to kolejne odcienie barwy czerwonej, drugi zielonej, a trzeci niebieskiej.  Cała operacja rysowania zawarta jest w funkcji Draw() obiektu BView i polega na zmianie koloru i współrzędnych dwóch obiektów BPoint, wykorzystywanych później do narysowania linii: 

BPoint poczatek; 
BPoint koniec; 
int l; 
for (l=0;l<255;l++) 
{ 
//czerwony: 
SetHighColor(l,0,0,255); 
poczatek.Set(45,20+l); 
koniec.Set(105,20+l); 
StrokeLine(poczatek,koniec); 

//zielony 
SetHighColor(0,l,0,255); 
poczatek.Set(125,20+l); 
koniec.Set(185,20+l); 
StrokeLine(poczatek,koniec); 

//niebieski 
SetHighColor(0,0,l,255); 
poczatek.Set(205,20+l); 
koniec.Set(265,20+l); 
StrokeLine(poczatek,koniec); 
}

A cały kod źródłowy wygląda następująco: 

Plik Widok.h:

//plik nagłówkowy definiujący klasę widoku 
#ifndef _WIDOK_H_ 
#define _WIDOK_H_ 

#include%lt;View.h> 

extern BRect obszarwidoku; 

class Klasą_widoku : public BView 
    { 
    public: 
        Klasą_widoku(); 
        virtual void Draw(BRect); 
    }; 
#endif​

Plik Widok.cpp:

#include"Widok.h" 

BRect obszarwidoku(0,0,340,365); 

Klasą_widoku::Klasą_widoku():BView (obszarwidoku,"widok",B_FOLLOW_ALL,B_WILL_DRAW) 
    { 
    } 

void Klasą_widoku::Draw(BRect) 
    { 
    BPoint poczatek; 
    BPoint koniec; 
    int l; 
    for (l=0;l<255;l++) 
        { 
        //czerwony: 
        SetHighColor(l,0,0,255); 
        poczatek.Set(45,20+l); 
        koniec.Set(105,20+l); 
        StrokeLine(poczatek,koniec); 

        //zielony 
        SetHighColor(0,l,0,255); 
        poczatek.Set(125,20+l); 
        koniec.Set(185,20+l); 
        StrokeLine(poczatek,koniec); 

        //niebieski 
        SetHighColor(0,0,l,255); 
        poczatek.Set(205,20+l); 
        koniec.Set(265,20+l); 
        StrokeLine(poczatek,koniec); 

        } 

    SetHighColor(0,0,0,255); 
    DrawString("Program przykładowy ze strony And3mD Haiku Dev.",BPoint(15,310)); 
    DrawString("www.haikudev.prv.pl",BPoint(95,325)); 
    }
​

Plik Okno.h:

//Plik nagłówkowy definiujący klasę okna 
#ifndef _OKNO_H_ 
#define _OKNO_H_ 

#include<Window.h> 
#include"Widok.h" 

extern BRect obszarokna; 

class Klasą_Okna : public BWindow 
    { 
    public: 
        Klasą_Okna(); 
        virtual bool QuitRequested(); 
        Klasą_widoku * Widok; 
    }; 
#endif​

Plik Okno.cpp:

/* 
        Plik źródłowy Okno.cpp zawierający definicje funkcji 
*/ 
#include"aplikacją.h" 
#include"Okno.h" 

BRect obszarokna(30,30,340,365); 

bool Klasą_Okna::QuitRequested() 
    { 
    be_app->PostMessąge(B_QUIT_REQUESTED); 
    return(true); 
    } 

Klasą_Okna::Klasą_Okna():BWindow (obszarokna,"Kolory",B_TITLED_WINDOW,B_NOT_RESIZABLE, B_CURRENT_WORKSPACE)
    { 
    Widok = new Klasą_widoku; 
    AddChild(Widok); 
    }​

Plik Aplikacja.h:

//Plik nagłówkowy definiujący klasę aplikacji 
#ifndef _aplikacją_H_ 
#define _aplikacją_H_ 

#include <Application.h> 
#include"Okno.h" 

class aplikacją : public BApplication 
    { 
    public: 
        aplikacją(); 

        Klasą_Okna * POkno; 
    }; 
#endif​

Plik Aplikacja.cpp:

#include"aplikacją.h" 

int main() 
    { 
    new aplikacją(); 
    be_app->Run(); 
    delete be_app; 
    } 

aplikacją::aplikacją():BApplication ("application/obiektwidoku") 
    { 
    POkno = new Klasą_Okna; 
    POkno->Show(); 
    POkno->Widok->Show(); 
    }​

Okno programu przykładowego powinno wyglądać następująco: 

Rys.1 Program przykładowy Kolory 1.0.

Program przykładowy można pobrać stąd [Link].  wróc do indeksu 


 Część 9 - BView - zarządzanie pisakiem  Najważniejszą opcją pisaka jest zmiana grubości konturów rysowanych figur lub w przypadku linii zmiana jej szerokości. Zmianę grubości pisaka umożliwia nam funkcja SetPenSize() o składni:  

virtual void SetPenSize(float size);

Aktualnie ustawiony rozmiar pisaka możemy odczytać za pomocą funkcji PenSize() o składni: 

float PenSize(void);

Niektóre funkcje rysujące wykorzystują aktualną pozycję pisaka jako punkt, z którego rozpoczynają operację rysowania, a także zmieniają jego położenie na punkt w którym zakończyły rysowanie np. StrokeLine() w wersji bez argumentu określającego punkt początkowy.  Pozycję pisaka możemy też zmieniać nie rysując niczego na ekranie za pomocą funkcji MovePenTo() lub MovePenBy().  Funkcja MovePenBy():  Funkcja MovePenBy() przesuwa pisak o określone za pomocą argumentów horizontal i vertical odległości. 

Składnia funkcji MovePenBy():
void MovePenBy(float horizontal, float vertical);

 

Opis argumentów funkcji MovePenBy():
horizontal wartość, o którą zostanie przesunięty pisak w kierunku poziomym
vertical wartość, o którą zostanie przesunięty pisak w kierunku pionowym

Na przykład, aby przesunąć pisak o 5 punktów w prawo i o 4 w dół wystarczy: 

MovePenBy(5,4);

Funkcja MovePenTo():  Funkcja MovePenTo() umożliwia przesunięcie pisaka na pozycję określoną przez współrzędne zapisane albo w obiekcie typu BPoint, albo za pomocą dwóch zmiennych typu float x,y. 

Składnia funkcji MovePenTo():
void MovePenTo(BPoint point);  void MovePenTo(float x, float y);

 

Opis argumentów funkcji MovePenTo():
point obiekt typu BPoint określający pozycję, na którą zostanie przesunięty pisak.
x nowa współrzędna x pisaka
y nowa współrzędna y pisaka

Odczytanie pozycji pisaka:  Odczytanie aktualnej pozycji pisaka jest równie proste jak jej zmiana. Służy do tego funkcja PenLocation(): 

Składnia funkcji PenLocation():
BPoint PenLocation();

Funkcja PenLocation() nie przyjmuje żadnych argumentów, a wartością przez nią zwracaną jest aktualna pozyca pisaka zapisana w obiekcie typu BPoint.  Program przykładowy:  Program przykładowy wykorzystuje funkcję Draw() do narysowania kolejno linii o grubości 1,2,3,4,5.  Linie rysowane są za pomocą funkcji StrokeLine() z jednym argumentem, określającym punkt końcowy rysowanej linii, czyli jako punkt początkowy wykorzystywana jest aktualna pozycja pisaka. Aby rysowane linie były równoległe, pozycja pisaka zmieniana jest za pomocą funkcji MovePenTo(): 

BPoint konieclinii; 

MovePenTo(45,30);//zmiana pozycji pisaka 
konieclinii.Set(265,30); 
StrokeLine(konieclinii);//rys. linii do punktu konieclinii 

SetPenSize(2);//zmiana rozmiaru pisaka 
MovePenTo(45,60);//zmiana pozycji pisaka 
konieclinii.Set(265,60); 
StrokeLine(konieclinii);//rys. linii do punktu konieclinii 

SetPenSize(3);//zmiana rozmiaru pisaka 
MovePenTo(45,90);//zmiana pozycji pisaka 
konieclinii.Set(265,90); 
StrokeLine(konieclinii);//rys. linii do punktu konieclinii 

SetPenSize(4);//zmiana rozmiaru pisaka 
MovePenTo(45,120);//zmiana pozycji pisaka 
konieclinii.Set(265,120); 
StrokeLine(konieclinii);//rys. linii do punktu konieclinii 

SetPenSize(5);//zmiana rozmiaru pisaka 
MovePenTo(45,150);//zmiana pozycji pisaka 
konieclinii.Set(265,150); 
StrokeLine(konieclinii);//rys. linii do punktu konieclinii

Pełny kod źródłowy wygląda następująco: 

Plik Widok.h:

//plik nagłówkowy definiujący klasę widoku 
#ifndef _WIDOK_H_ 
#define _WIDOK_H_ 

#include<View.h> 

extern BRect obszarwidoku; 

class Klasą_widoku : public BView 
    { 
    public: 
        Klasą_widoku(); 
        virtual void Draw(BRect); 
    }; 
#endif​

Plik Widok.cpp:

#include"Widok.h" 

BRect obszarwidoku(0,0,340,265); 

Klasą_widoku::Klasą_widoku():BView (obszarwidoku,"widok",B_FOLLOW_ALL,B_WILL_DRAW) 
    { 
    } 

void Klasą_widoku::Draw(BRect) 
    { 
    BPoint konieclinii; 

    MovePenTo(45,30); 
    konieclinii.Set(265,30); 
    StrokeLine(konieclinii); 

    SetPenSize(2); 
    MovePenTo(45,60); 
    konieclinii.Set(265,60); 
    StrokeLine(konieclinii); 

    SetPenSize(3); 
    MovePenTo(45,90); 
    konieclinii.Set(265,90); 
    StrokeLine(konieclinii); 

    SetPenSize(4); 
    MovePenTo(45,120); 
    konieclinii.Set(265,120); 
    StrokeLine(konieclinii); 

    SetPenSize(5); 
    MovePenTo(45,150); 
    konieclinii.Set(265,150); 
    StrokeLine(konieclinii); 

    DrawString("Program przykładowy ze strony And3mD Haiku Dev.",BPoint(15,210)); 
    DrawString("www.haikudev.prv.pl",BPoint(95,225)); 
    }​

Plik Okno.h:

//Plik nagłówkowy definiujący klasę okna 
#ifndef _OKNO_H_ 
#define _OKNO_H_ 

#include<Window.h> 
#include"Widok.h" 

extern BRect obszarokna; 

class Klasą_Okna : public BWindow 
    { 
    public : 
        Klasą_Okna(); 
        virtual bool QuitRequested(); 

        Klasą_widoku * Widok; 
    }; 
#endif

Plik Okno.cpp:

/* 
        Plik źródłowy Okno.cpp zawierający definicje funkcji 
*/ #include"aplikacją.h" 
#include"Okno.h" 

BRect obszarokna(30,30,340,265); 

bool Klasą_Okna::QuitRequested() 
    { 
    be_app->PostMessąge(B_QUIT_REQUESTED); 
    return(true); 
    } 

Klasą_Okna::Klasą_Okna():BWindow(obszarokna,"Pen Size",B_TITLED_WINDOW,B_NOT_RESIZABLE,B_CURRENT_WORKSPACE) 
    { 
    Widok = new Klasą_widoku; 
    AddChild(Widok); 
    }​

Plik aplikacją.h:

//Plik nagłówkowy definiujący klasę aplikacji 
#ifndef _aplikacją_H_ 
#define _aplikacją_H_ 

#include <Application.h> 
#include"Okno.h" 

class aplikacją : public BApplication 
    { 
    public: 
        aplikacją(); 
        Klasą_Okna * POkno; 
    }; 
#endif​

Plik aplikacją.cpp:

#include"aplikacją.h" 

int main() 
    { 
    new aplikacją(); 
    be_app->Run(); 
    delete be_app; 
    } 

aplikacją::aplikacją():BApplication ("application/obiektwidoku") 
    { 
    POkno = new Klasą_Okna; 
    POkno->Show(); 
    POkno->Widok->Show(); 
    }​

Okno programu przykładowego powinno wyglądać następująco: 

Rys.1 Program przykładowy Pen Size 1.0.

Program przykładowy można pobrać stąd [Link].  wróc do indeksu 


 Część 10 - Obsługa czcionek w systemach BeOS/Haiku  Mechanizm obsługi czcionek w BeOSie/Haiku możemy podzielić na trzy zasadnicze części:  

  • funkcje globalne dotyczące czcionek fizycznych (pobieranie listy czcionek, ich nazw i styli)
  • klasę BFont, odpowiedzialną za przechowywanie atrybutów czcionek logicznych
  • funkcje obsługi czcionek w innych klasach (np. BView) umożliwiające zmianę przypisanego do danego obiektu fontu lub niektórych jego atrybutów.

Czcionki fizyczne: Czcionki fizyczne są to czcionki zainstalowane w systemie, zapisane np. w plikach *.ttf. W systemie BeOS czcionki znajdują się w podkatalogach katalogów: 

/boot/home/config/fonts/ 
/boot/beos/etc/fonts/

Czcionki logiczne:  Czcionka logiczna jest to abstrakcyjny rodzaj zapisu wszystkich atrybutów fontu takich jak wielkość, styl, rodzina. W BeOSie/Haiku do tego zapisu wykorzystywana jest klasa BFont.  Najłatwiej opis mechanizmu obsługi czcionek zacząć od czcionek fizycznych ponieważ to na ich podstawie tworzymy fonty logiczne, które są wykorzystywane do zmiany kroju pisanego tekstu w jakimkolwiek obiekcie GUI.  Ta część kursu zostanie więc poświęcona czcionkom fizycznym, kolejna czcionkom logicznym (klasie BFont). Dopiero po nich wrócimy do klasy BView aby omówić funkcje obsługi tekstu. 

Czcionki zainstalowane w systemie:  Obsługa czcionek fizycznych we wszystkich systemach operacyjnych jest dość zagmatwana z jednego powodu: 

Nigdy nie wiadomo jakie czcionki zainstalował/odinstalował użytkownik, dodatkowo lista ta może zmienić się w każdym momencie (użytkownik może praktycznie w dowolnej chwili doinstalować/odinstalować jakąś czcionkę).

Dwoma podstawowymi atrybutami czcionek pozwalającymi je w jakiś sposób skatalogować są: 

  • rodzina czcionki
  • styl czcionki

Listę rodzin czcionek i ich styli w BeOSie/Haiku możemy odczytać za pomocą kombinacji kilku funkcji globalnych.  Rodziny czcionek:  Najprościej mówiąc rodzina czcionek jest to nazwa czcionki np. Times New Roman, Courier itd. Aby wyliczyć nazwy rodzin czcionek zainstalowanych w danym systemie korzystamy z funkcji globalnych count_font_families() i get_font_family().  Pierwsza z nich count_font_families() o składni: 

int32 count_font_families(void)

zwraca ilość rodzin czcionek zainstalowanych w systemie. W BeOSie/Haiku każda rodzina czcionek ma swój numer, będący liczbą całkowitą bez znaku. Numer ten jednoznacznie wskazuje na daną rodzinę czcionek.  Druga funkcja get_font_family() zwraca nazwę rodziny czcionki o określonym indeksie. 

Składnia funkcji get_font_family():
status_t get_font_family(int32 index, font_family *family, uint32 *flags = NULL);

 

Opis argumentów funkcji get_font_family():
index indeks rodziny czcionek której chcemy pobrać nazwę
family zmienna typu font_family, której zostanie przypisana nazwa rodziny czcionek

Style czcionki:  Drugim z najważniejszych atrybutów czcionki jest styl. Czcionka może obsługiwać jeden lub kilka z niżej wymienionych styli: 

  • regular (regularna)
  • italic (kursywa)
  • bold (pogrubiebnie)
  • bold italic (pogrubiona kursywa)

Aby sprawdzić jakie style obsługuje dana rodzina czcionek wykorzystujemy funkcje globalne count_font_styles() i get_font_style():  Funkcja count_font_styles() o składni: 

int32 count_font_styles(font_family family)

zwraca ilość styli obsługiwanych przez daną czcionkę, a funkcja get_font_style() zwraca nazwę stylu o podanym indeksie. 

Składnia funkcji get_font_style():
status_t get_font_style(font_family family, int32 index, font_style *style, uint32 *flags = NULL)

 

Opis argumentów funkcji get_font_style():
family nazwa rodziny czcionek
index numer (indeks) stylu, którego nazwę chcemy pobrać
style zmienna typu font_style do której zostanie zwrócona nazwa stylu

Program przykładowy: 
Jako przykład użycia tych funkcji napiszemy program, który będzie wyświetlał nazwy dziesięciu pierwszych rodzin czcionek i obsługiwane przez nie style. Do wyświetlania tekstu użyjemy funkcję DrawString(), o której więcej napiszę w dwunastej części kursu.  Cały silnik aplikacji, wyświetlający kolejno pierwsze 10 nazw rodzin czcionek i obsługiwane przez nie style zawarty jest w funkcji Draw() klasy widoku.  Na początku tej funkcji definiujemy zmienne, w których funkcje get_font_family() i get_font_style() będą zapisywać kolejne nazwy rodzin czcionek (zmienna rodzina) i nazwy styli dla określonej czcionki (zmienna styl). 

font_family rodzina;//zmienna, która będzie przechowywać nazwę rodziny 
font_style styl;//zmienna, która będzie przechowywać styl 

Następnie definiujemy zmienne które będą przechowywać ilość rodzin czcionek (zmienna ilosc_rodzin) i liość styli (zmienna ilosc_styli) dla danej czcionki: 

uint32 ilosc_rodzin;//zmienna, która będzie przechowywać ilość rodzin czcionek zainstalowanych w systemie 
uint32 ilosc_styli;//zmienna, która będzie przechowwać ilość styli danej czcionki

Po zdefiniowaniu tych zmiennych, pobieramy ilość czcionek zainstalowanych w systemie za pomocą funkcji count_font_families():

ilosc_rodzin= count_font_families();

Po pobraniu ilości czcionek za pomocą instrukcji warunkowej if, wybierana jest jedna z dwóch pętli. Każda z tych pętli wykonuje te same operacje ale dla innej ilości zainstalowanych czcionek. Pierwsza wykonywana jest gdy w systemie zainstalowanych jest co najmniej 10 czcionek, a druga w jeżeli jest ich mniej. Licznik naszych pętli wykorzystywany jest na dwa sposoby: 

  • jako nr (indeks) czcionki której nazwę chcemy pobrać za pomocą funkcji get_font_family(),
  • przy ustalaniu współrzędnych miejsca w którym należy wypisać nazwę czcionki

Po wyświetleniu nazwy czcionki pobierana jest ilość obsługiwanych przez nią styli, które następnie są wyświetlane wykorzystując do tego podpętlę: 

if (ilosc_rodzin>9) 
for (uint32 indekscz=0;indekscz<10;indekscz++) 
{ 
//pobranie nazwy rodziny czcionek o indeksie indekscz 
get_font_family(indekscz,&rodzina,NULL); 
// wyświetlenie nazwy rodziny czcionki 
DrawString(rodzina,BPoint(15,(30+20*indekscz))); 
ilosc_styli=count_font_styles(rodzina); 
for(uint32 indeks_styl=0;indeks_styl<ilosc_styli;indeks_styl++) 
{ 
get_font_style(rodzina,indeks_styl,&styl); 
DrawString(styl,BPoint(190+70*indeks_styl,(30+20*indekscz))); 
} 
} 
else//jeżeli czcionek jest mniej niż 10 
for (uint32 indekscz=0;indekscz<ilosc_rodzin;indekscz++) 
{ 
get_font_family(indekscz,&rodzina,NULL); 
// wyświetlenie nazwy rodziny czcionki 
DrawString(rodzina,BPoint(15,(30+20*indekscz))); 
//pobranie ilości styli dla danej czcoinki 
ilosc_styli=count_font_styles(rodzina); 
for(uint32 indeks_styl=0;indeks_styl<ilosc_styli;indeks_styl++) 
{ 
get_font_style(rodzina,indeks_styl,&styl); 
DrawString(styl,BPoint(190+70*indeks_styl,(30+20*indekscz))); 
} 
}

Cały kod źródłowy wygląda następująco: 

Plik Widok.h:

//plik nagłówkowy definiujący klasę widoku 
#ifndef _WIDOK_H_ 
#define _WIDOK_H_ 

#include<View.h> 

extern BRect obszarwidoku; 

class Klasą_widoku : public BView 
    { 
    public : 
        Klasą_widoku(); 
        virtual void Draw(BRect); 
    }; 
#endif

Plik Widok.cpp:

#include"Widok.h" 

BRect obszarwidoku(0,0,600,300); 

Klasą_widoku::Klasą_widoku():BView(obszarwidoku,"widok",B_FOLLOW_ALL,B_WILL_DRAW) 
    { 
    } 

void Klasą_widoku::Draw(BRect) 
    { 
    font_family rodzina;//zmienna, która będzie przechowywać nazwę rodziny 
    font_style styl;//zmienna, która będzie przechowywać styl 
    uint32 ilosc_rodzin;//zmienna, która będzie przechowywać ilość rodzin czcionek zainstalowanych w systemie 
    uint32 ilosc_styli;//zmienna, która będzie przechowwać ilość styli danej czcionki 

    //pobranie liczby rodzin czcionek 
    ilosc_rodzin= count_font_families(); 

    if (ilosc_rodzin>9) 
    for (uint32 indekscz=0;indekscz<10;indekscz++) 
        { 
        //pobranie nazwy rodziny czcionek o indeksie indekscz 
        get_font_family(indekscz,&rodzina,NULL); 
        // wyświetlenie nazwy rodziny czcionki 
        DrawString(rodzina,BPoint(15,(30+20*indekscz))); 
        ilosc_styli=count_font_styles(rodzina); 
        for(uint32 indeks_styl=0;indeks_styl<ilosc_styli;indeks_styl++) <br="">             { 
            get_font_style(rodzina,indeks_styl,&styl); 
            DrawString(styl,BPoint(190+70*indeks_styl,(30+20*indekscz))); 
            } 
        } 
    else//jeżeli czcionek jest mniej niż 10 
        for (uint32 indekscz=0;indekscz<ilosc_rodzin;indekscz++) <br="">             { 
            get_font_family(indekscz,&rodzina,NULL); 
            // wyświetlenie nazwy rodziny czcionki 
            DrawString(rodzina,BPoint(15,(30+20*indekscz))); 
            // pobranie ilości styli dla danej czcionki 
            ilosc_styli=count_font_styles(rodzina); 
            for(uint32 indeks_styl=0;indeks_styl<ilosc_styli;indeks_styl++) <br="">                 { 
                get_font_style(rodzina,indeks_styl,&styl); 
                DrawString(styl,BPoint(190+70*indeks_styl,(30+20*indekscz))); 
                } 
            } 

    DrawString("Program przykładowy ze strony And3mD Haiku Dev.",BPoint(15+135,250)); 
    DrawString("www.haikudev.prv.pl",BPoint(90+140,265)); 
    }​

Plik Okno.h:

//Plik nagłówkowy definiujący klasę okna 
#ifndef _OKNO_H_ 
#define _OKNO_H_ 

#include<Window.h> 
#include"Widok.h" 

extern BRect obszarokna; 

class Klasą_Okna : public BWindow 
    { 
    public : 
        Klasą_Okna(); 
        virtual bool QuitRequested(); 

        Klasą_widoku * Widok; 
    }; 
#endif​

Plik Okno.cpp:

/* 
        Plik źródłowy Okno.cpp zawierający definicje funkcji klasy okna 
*/ 

#include"aplikacją.h" 
#include"Okno.h" 

BRect obszarokna(30,30,600,300); 

bool Klasą_Okna::QuitRequested() 
    { 
    be_app->PostMessąge(B_QUIT_REQUESTED); 
    return(true); 
    } 

Klasą_Okna::Klasą_Okna():BWindow(obszarokna,"Czcionki",B_TITLED_WINDOW,B_NOT_RESIZABLE,B_CURRENT_WORKSPACE)
    { 
    Widok = new Klasą_widoku; 
    AddChild(Widok); 
    }​

Plik aplikacją.h:

//Plik nagłówkowy definiujący klasę aplikacji 
#ifndef _aplikacją_H_ 
#define _aplikacją_H_ 

#include <Application.h> 
#include"Okno.h" 

class aplikacją : public BApplication 
    { 
    public : 
        aplikacją(); 

        Klasą_Okna * POkno; 
    }; 
#endif

Plik aplikacją.cpp:

#include"aplikacją.h" 

int main() 
    { 
    new aplikacją(); 
    be_app->Run(); 
    delete be_app; 
    } 

aplikacją::aplikacją():BApplication("application/czcionki") 
    { 
    POkno = new Klasą_Okna; 
    POkno->Show(); 
    }

Przykładowe wyniki uruchomienia programu (lista czcionek zależy od zainstalowanych fontów): 


Rys.1 Program przykładowy Czcionki 1.0.



Program przykładowy można pobrać stąd [Link]. 

wróc do indeksu 


  

Autor & Copyrights 

Autor: 

Autorem serwisu And3mD Haiku Dev jest Andrzej "And3mD" Kilijański. 

Kontakt: wszelkie sugestie, wnioski proszę wysyłać na adres: Ten adres pocztowy jest chroniony przed spamowaniem. Aby go zobaczyć, konieczne jest włączenie w przeglądarce obsługi JavaScript. 

Copyrights: 

Autor prosi o uszanowanie jego pracy, i nie zezwala na kopiowanie prezentowanych treści. 

Jeżeli chcesz wesprzeć to co robię dodaj link na swojej stronce zamiast kopiować moją pracę:) 

Osoby, które uzyskały zgodę na umieszczenie poprzedniej wersji kursu (tej ze strony And3mD online) w swoich projektach lub na swoich stronach NIE MAJą takiej zgody co do materiałów prezentowanych w serwisie And3mD Haiku Dev. Tyczy się to nietylko nowych tekstów, ale także dokonywania aktualizacji. 

Pozdrowienia: 

Przede wszystkim jak zwykle :) dla mojej dziewczyny Moniki:* 

I rasta dnb brata: Arta 
A także dla Kolca, łukasza, Cyca, Orma, Krystiana, Luke, Anki, Ewy i wszystkich innych których nie wymieniłem na tej krótkiej liście! :) 

wróc do indeksu 




Tutorial Andrzej Kiljanski (And3mD ) marzec 2004
Dostepne przez BeSly w Haiku, BeOS i bazy wiedzy Zeta.