Jarosław Kuchta Podstawy Programowania Obiektowego Podstawy grafiki obiektowej
Zagadnienia Grafika proceduralna grafika obiektowa Grafika WPF dualizm XAML C# Właściwości obiektów graficznych edycja właściwości Grafika w kodzie C# Właściwości "dołączane" Zdarzenia połączenie XAML C#
Grafika proceduralna rysowanie za pomocą kontekstu graficznego w Windows wymaga dobrej znajomości wszystkich parametrów procedur graficznych wymaga odpowiedniej kolejności wywoływania procedur graficznych PAINTSTRUCT ps; HDC hdc = BeginPaint(hWindow, &ps); GamePaint(hDC); EndPaint(hWindow, &ps); void GamePaint(HDC hdc) { RECT rect; GetClientRect(hWindow, &rect); DrawText(hDC, TEXT("SuperBall"), -1, &rect, DT_SINGLELINE DT_CENTER DT_VCENTER); MoveToEx(hDC, 10, 40, NULL); LineTo(hDC, 44, 10); LineTo(hDC, 78, 40); }
Grafika obiektowa deklarujemy obiekt klasy "płótno" (Canvas) umieszczamy na płótnie obiekty graficzne: prostokąt (Rectangle) elipsę (Ellipse) linię (Line) ścieżkę (Path) wielolinię (Polyline) wielokąt (Polygon) Stosujemy projektowanie wizualne (What You See Is What You Get) Określamy ich właściwości Płótno "samo" odrysowuje umieszczone na nim obiekty
Windows Presentation Framework Dualizm XAML C# (programowanie "code behind") XAML projekt wizualny strony graficznej zapis "znacznikowy" (XML) C# - kod manipulujący obiektami strony graficznej Projekt: kod C#: XAML:
XAML język znacznikowy Windows Oparty o uniwersalny język znacznikowy XML nazwa elementu XML nazwa klasy WPF znacznik otwierający obiekt znacznik otwierający właściwość znacznik zamykający właściwość znacznik zamykający obiekt nazwa klasy w C# przestrzenie nazw XML właściwości obiektów obiekty zagnieżdżone
Projektowanie wizualne Panel edycji kodu XAML Panel edycji wizualnej Okno edycji strony wizualnej
Dodawanie elementów Toolbox zawiera listę dostępnych obiektów graficznych i innych "kontrolek" (controls) Przeciągnięcie obiektu z toolboxa na powierzchnię projektu powoduje dodanie obiektu do projektu. Dodawany obiekt zostanie umieszczony wewnątrz obiektu, na który został przeciągnięty
Edycja właściwości obiektów Właściwości obiektów możemy zmieniać w kodzie XAML albo w panelu właściwości. Manipulacja obiektem na ekranie też zmienia niektóre właściwości.
Podstawowe właściwości wszystkich elementów WPF Klasa FrameworkElement: Name nazwa obiektu Parent obiekt nadrzędny (zawierający) HorizontalAlignment, VerticalAlignment sposób wyrównania do obiektu nadrzędnego Margin margines (odstęp od krawędzi obiektu nadrzędnego) Width, Height projektowana szerokość i wysokość kształtu MinWidth, MinHeight minimalna szerokość i wysokość MaxWidth, MaxHeight maksymalna szerokość i wysokość ActualWidth, ActualHeight aktualna szerokość i wysokość Visibility czy obiekt jest widoczny Opacity stopień nieprzezroczystości (0-przezroczysty, 1-nieprzezroczysty)
Podstawowe właściwości wszystkich kształtów Klasa Shape: FrameworkElement: Fill sposób wypełnienia (obiekt klasy Brush) Stroke sposób rysowania (obiekt klasy Brush) StrokeThickness grubość linii rysowania StrokeDashArray tablica opisująca wzór dla linii przerywanej StrokeDashOffset przesunięcie wzoru linii przerywanej StrokeStartLineCap, StrokeEndLineCap sposób zakończenia rysowania linii (z obu stron) StrokeDashCap sposób zakończenia segmentów linii przerywanej StrokeLineJoin sposób łączenia segmentów linii StrokeMiterLimit parametr dla jednego ze sposobów łączenia segmentów linii
Rysowanie linii Klasa Line: Shape: X1,Y1 współrzędne pierwszego punktu X2, Y2 współrzędne drugiego punktu
Przykłady wzorów linii StrokeThickness="1" StrokeDashArray="1,2,1,2" StrokeThickness="1" StrokeDashArray="1,5,1,5" StrokeThickness="5" StrokeDashArray="1,2,1,2" StrokeThickness="5" StrokeDashArray="1,2,1,2" StrokeDashCap="Round" StrokeThickness="5" StrokeThickness="5" StrokeMitterLimit="1" StrokeThickness="5" StrokeLineJoin="Round"
Pędzel (Brush) Klasa definiująca sposób wypełnienia kształtu zamkniętego albo rysowania linii: SolidColorBrush wypełnienie jednolite GradientBrush wypełnienie gradientowe LinearGradientBrush wypełnienie gradientowe liniowe RadialGradientBrush wypełnienie gradientowe kołowe BitmapCacheBrush TileBrush
Wypełnienie jednolite Klasa SolidColorBrush: Color kolor wypełnienia Sposób definiowania koloru <SolidColorBrush Color="nazwa_koloru"/> <SolidColorBrush Color="#rgb"/> <SolidColorBrush Color="#argb"/> <SolidColorBrush Color="#rrggbb"/> <SolidColorBrush Color="#aarrggbb"/> <SolidColorBrush Color="sc#scA,scR,scG,scB"/> Składowe: A nieprzezroczystość (Alpha) R czerwona (Red) G zielona (Green) B niebieska (Blue) sc składowa wyrażona jako liczba rzeczywista od 0 do 1
Predefiniowane kolory (1)
Predefiniowane kolory (2)
Wypełnienie gradientowe liniowe Klasa LinearGradientBrush: StartPoint, EndPoint współrzędne początku i końca linii wypełniania GradientStops wartości koloru na linii
Wypełnienie gradientowe Klasa RadialGradientBrush: liniowe GradientOrigin współrzędne początku wypełniania RadiusX, RadiusY promienie (poziomy i pionowy) elipsy wypełniania GradientStops wartości koloru wzdłuż promienia
Rysowanie wielokąta Klasa Polygon: Shape: Points współrzędne kolejnych punktów
Klasa Path: Shape: Rysowanie ścieżki (geometria) Data dane ścieżki (geometria - PathGeometry)
Skrócony zapis geometrii ścieżki M Move (przesunięcie) X, Y L Line (odcinek linii prostej) X, Y H Horizontal (odcinek linii poziomej) X V Vertical (odcinek linii pionowej) Y C Curve (odcinek krzywej Beziera) CP1, CP2 A Arc (odcinek łuku) Rx, Ry, Rot, L, S, X, Y Z Zero (zamknięcie krzywej)
Grafika w kodzie C# Zamiast konstruować obiekty graficzne w kodzie XAML, można to robić w kodzie C# Zastosowanie tam, gdzie obiekty muszą być konstruowane dynamicznie
Manipulowanie właściwościami w kodzie C# W kodzie C# można manipulować właściwościami obiektów graficznych tak samo, jak innych obiektów. Można też manipulować obiektami graficznymi tak samo, jak innymi obiektami.
Właściwości "dołączane" Właściwości "dołączane" są zdefiniowane w innej klasie niż sam obiekt. W ten sposób można zdefiniować właściwości dla klas już zamkniętych. Właściwości Canvas.Left i Canvas.Top, chociaż są zdefiniowane w klasie Canvas, to określają położenie prostokąta (Rectangle)
Manipulacja właściwościami dołączanymi w kodzie C# Aby odczytać właściwość Left, trzeba użyć metody statycznej GetLeft klasy Canvas Aby zmienić właściwość Top, trzeba użyć metody statycznej SetLeft klasy Canvas.
Zdarzenia Procedury w kodzie są wykonywane w reakcji na tzw. zdarzenia (event). Zdarzenie określa sytuację, w której coś następuje. Każda klasa WPF ma zdefiniowane zdarzenia, np.: SizeChanged zmiana rozmiaru Click naciśnięcie przycisku Programista definiuje tzw. procedurę obsługi zdarzenia. Procedura jest wywoływana przy nastąpieniu zdarzenia.
Definiowanie procedur obsługi zdarzeń Aby zdefiniować procedurę obsługi zdarzenia wystarczy otworzyć zakładkę "Events" na panelu właściwości i dwa razy kliknąć puste pole na określonej pozycji. Procedura jest tworzona (wraz z parametrami), a jej adres wpisywany jako właściwość do obiektu.
Wypełnianie procedury kodem Automatycznie otwierane jest okno edycji kodu, gdzie programista wpisuje odpowiedni kod. Wskazane jest tworzenie osobnych procedur manipulacji obiektami graficznymi i wywoływanie ich z procedur obsługi zdarzeń. Dzięki temu ta sama procedura manipulacji może być wielokrotnie wykorzystana przy różnych zdarzeniach.
Wnioski Zastosowanie techniki obiektowej umożliwia dużo łatwiejsze manipulowanie grafiką niż w przypadku podejścia proceduralnego. Projektowanie wizualne umożliwia natychmiastowe zobaczenie strony wizualnej programu. Warto projektować wizualnie początkowy obraz strony, a manipulować obiektami graficznymi w kodzie. Trzeba pamiętać, że procedury manipulacji zapisane w kodzie są wywoływane w reakcji na zdarzenia.