Jak zacząć Prosty program (tiny.cpp): ////////////////////////////////////////////////////////////////// #include "basic.h" // Klasa reprezentująca główne okno aplikacji, musi dziedziczyc Frame class MyFrame : public Frame { public: MyFrame() ; } ; // Konstruktor: tytuł, położenie (x,y) i rozmiar (szer.,wys.) MyFrame::MyFrame() : Frame("Tiny", 0,0,200,200){} // Klasa aplikacji, dziedziczy App; musi istniec jeden obiekt tej klasy class MyApp:public App { MyFrame *frame ; void onInit() ; } ; // Wywoływane przy starcie aplikacji void MyApp::onInit() { frame = new MyFrame ; setMainWindow(frame) ; } int main() { MyApp().run(); } ////////////////////////////////////////////////////////////////// Dodajemy obsługę klawiatury (small.cpp): class MyApp:public App { MyFrame *frame ; virtual void onInit() ; virtual bool onKeyPressed(int key) { if(key == 'q') {App::quit() ;return true;} return false ; } } ; Wypełnianie okna treścią Klasa Frame (a w zasadzie jej nadklasa, MWindow) posiada wirtualną metodę void paint() metoda ta jest wywoływana kiedy potrzebne jest odświeżenie zawartości okna (przy utworzeniu, zmianie rozmiaru, odsłonięciu okna). Musimy przedefiniować ją w naszej klasie (MyFrame), np. class MyFrame : public Frame { public: MyFrame() ; void paint() ; void onClick(int,int); // o tej metodzie za chwilę } ; void MyFrame::paint() { drawLine(10,10,100,100) ; // rysuje linię od (10,10) do (100,100) } Do rysowania, mamy następujące metody: drawPoint(int x,int y) ; // punkt drawLine(int x1,int x2,int y1, int y2) ; // linia od (x1,y1) do (x2,y2) drawRectangle(int x,int y,int w, int h) ; // prostokąt: x,y,szerokość,wysokość fillRectangle(int x,int y,int w, int h) ; // toż, wypełniony drawCircle(int x, int y, int r); // okrag fillCircle(int x, int y, int r); // kolo drawArc(int x,int y,int w, int h,int angle1, int angle2); // wycinek luku fillArc(int x,int y,int w, int h,int angle1, int angle2); // wycinek kola dwie ostatnie metody --- man XDrawArc drawString (int x, int y, string text ) ; // napis clear() ; // wyczyść okno Kolory i klasa Rgb Klasa Rgb Reprezentuje kolory w kodowaniu RGB (Red, Green Blue) Kolor jest reprezentowany przez intensywność składników: czerwonego, zielonego i niebieskiego (0-255). Przykłady: const Rgb red(255,0,0) ; // czerwony const Rgb lime(0,255,0) ; // jasny zielony const Rgb blue(0,0,255); // niebieski const Rgb white(255,255,255) ; // biały const Rgb black(0,0,0) ; // czarny const Rgb magenta(255,0,255); // fioletowy const Rgb yellow(255,255,0); // żółty const Rgb cyan(0,255,255); // jasny niebieski const Rgb green(0,128,0); // (ciemny) zielony Do ustawiania koloru tła i rysowania służą metody void setBackground(Rgb c) {setBackground(Color(c));}; void setForeground(Rgb c) {setForeground(Color(c));}; Przykład użycia - kolorowy kwadrat z czarną obwódką (btest.cpp) class Square { public: Square(int x, int y, int a, Rgb col) : m_x(x),m_y(y),m_a(a),m_col(col) {}; void draw(MWindow& win) ; private: int m_x, m_y, m_a; Rgb m_col ; }; void Square::draw(MWindow& win) { win.setForeground(m_col) ; win.fillRectangle(m_x,m_y,m_a,m_a) ; win.setForeground(black) ; win.drawRectangle(m_x,m_y,m_a,m_a) ; } Obsługa myszy Podstawowa - metoda onClick(int x,int y) wywoływana w momencie kliknięcia (argumentami są współrzędne wskaźnika myszy w oknie) Przykład: void MyFrame::onClick(int x, int y) { std::cout << "Click: x="<<x<<",y="<<y<<std::endl; } Zaawansowana - metody virtual void onLeftButtonDown(int,int) {}; virtual void onRightButtonDown(int,int) {} ; virtual void onLeftButtonUp(int x,int y) {onClick(x,y);}; virtual void onRightButtonUp(int,int){} ; wywoływane odpowiednio w momencie naciśnięcia i puszczenia lewego bądź prawego przycisku myszy. Uwaga: jeśli przedefiniujemy metodę onLeftButtonUp, to nie będzie wywoływana metoda onClick. Wszystkie wspomniane powyżej metody są zdefiniowane w klasie Clickable, która jest nadklasą MWindow (a więc i Frame) Gadżety - klasa Gadget Gadget reprezentuje element aplikacji, który ma - wygląd (sposób narysowania) - paint(MWindow& w) - reakcje na zdarzenia myszy - on...(x,y) - metodę przesunięcia o podany wektor - move - (ewentualnie) elementy (też klasy Gadget) - metodę dodawania nowych elementów - add Powyższe metody (z wyjątkiem add) są automatycznie propagowane do wszystkich elementów. Z punktu widzenia użytkownika, Gadget wygląda tak: class Gadget : public Clickable { public: void add(Gadget* c); virtual void onClick(int x, int y); virtual void paint(MWindow& win) ; virtual void move(int dx,int dy) ; }; Przykładem gadżetu może być napis: class GLabel:public Gadget { string m_text; int m_x,m_y; public: GLabel(int x, int y,string s):m_x(x),m_y(y),m_text(s){} void onClick(int,int){} void paint(MWindow& win){win.drawString(m_x,m_y,m_text);} }; Inny przykład użycia gadżetów (BoardSquare i PaletteSquare są podklasami klasy Gadget) Aplikacja składa się z dwóch obszarów: palety i planszy. Każdy z nich zawiera pewną ilość gadżetów. MyFrame::MyFrame() : Frame(0,"Clicker", 0,0,640,480) { const int squareSize = 32 ; palette.add(new PaletteSquare(0*squareSize,0*squareSize,squareSize,white)); palette.add(new PaletteSquare(1*squareSize,0*squareSize,squareSize,black)); //... for(int row=0;row<16;row++) for(int col=0;col<16;col++) board.add(new BoardSquare(col*squareSize, row*squareSize, squareSize, brush) ) ; palette.move(10,0); board.move(120,0); allGadgets.add(&palette); allGadgets.add(&board); } void MyFrame::paint() { allGadgets.paint(*this); } void MyFrame::onClick(int x, int y) { allGadgets.onClick(x,y); paint(); }