Witam w drugiej części przedzierania się przez chaszcze Ostrokrzewu. Jeśli daliście radę, to gratuluję, bo z wielu powodów to była jazda przez krzaczory na oślep. Po pierwsze to był mój pierwszy artykuł w życiu; po drugie forma dziennika, jaką sobie założyłem, chyba nie do końca mi wyszła; po trzecie, pisane na szybko i nie miałem czasu wszystkiego przemyśleć i ułożyć tak jakbym chciał. Mam nadzieję, że udało mi się zachować uniwersalność kodu, tak żeby można go użyć do skompilowania binarki albo apletu na systemach innych niż przeze mnie używany AmigaOS 4.1.
Na początku sprostuję pomyłkę z poprzedniego odcinka, którą sam wychwyciłem, a mianowicie napisałem:
„Musimy pamiętać, że styl czcionki jest resetowany na domyślny po każdym użyciu funkcji SetFont czy UseFont. Czyli znowu musimy użyć SetFontColor”.
To nie jest prawda w wypadku SetFontColor. Kolor raz ustawiony będzie używany do czasu aż go nie zmienimy na inny.
Dobra, pokutę mam za sobą, teraz ogłoszenia parafialne. W związku z tym, że wpisywanie ręcznie kodu widzianego w artykule bez możliwości skopiowania go może być mozolne (jest dostępny tylko na zrzutach ekranu), pomyślałem, że udostępnię pliki tekstowe do ściągnięcia:
www.czernik.me/hollywood.html
Ponadto postaram się skompilować binarki dla naszych amigowych systemów, a także dla Maca i Windy, i wrzucić je, żeby każdy mógł zassać i sprawdzić, czy i jak to działa u niego. To będzie szczególnie przydatne dla tych, którzy nie mają Hollywooda i nie mogą sami skompilować takiego programu. W pierwszej części to nie było bardzo istotne, bo wynik naszego programowania był dość prosty i nieruchomy. Inaczej będzie w tej części. Hollywood to prosty, ale całkiem mocny język i mimo swojej prostoty, pozwala na przedstawianie rzeczy na ekranie w sposób ograniczony przede wszystkim naszą wyobraźnią.
„Zaproszenie”, które było swojego rodzaju invitką na party, zostało zrobione w stu procentach, używając rozkazów/funkcji Hollwyood.
Nie ma tam wklejonych grafik czy jakichś niehollywoodowych sztuczek. Są natomiast czcionki ściągnięte z sieci. Mają one licencję pozwalającą na używanie ich do woli na użytek własny albo/i komercyjny i są zupełnie darmowe.
Podam listę, jeślibyście chcieli je u siebie zainstalować: Archistico, Elegant Lux Mager, Exo 2, Lato.
Odnośnie do przyjaznej instalacji czcionek w swoim systemie możecie poczytać pod adresem:
www.hollywood-mal.com/docs/html/hollywood/PrgG2KFonts.html
Na samym początku zajmiemy się funkcjami tworzenia obiektów tekstowych, a także wyświetlania i manipulowania nimi. Zarówno jeśli chodzi o wygląd jak i pozycję na ekranie. Bez lania wody przechodzimy do mięsa. Żeby cokolwiek wyświetlić, obrócić czy przesunąć musimy najpierw to stworzyć. W naszym tekstowym przypadku służy do tego funkcja:
CreateTextObject(id, text$[, table])
Działa ona jak deklaracja zmiennej w innych językach, z tą różnicą, że w naszym wypadku mamy możliwość przypisania naszej zmiennej różnych cech przekazywanych jako tablica – atrybut [, table]. Nasz tekst przekazujemy jako atrybut „text$”, „id” natomiast to identyfikator, który umożliwi nam odróżnienie naszego tekstu. Jeśli pominiemy opis cech przekazywanych poprzez [, table], to nasz tekst będzie wyświetlony z domyślnymi lub wcześniej w skrypcie ustawionymi atrybutami dla czcionki.
Mała dygresja odnośnie do dziwnego zapisu składni funkcji – wygląda tak, jakby przecinek był zamieniony miejscami z nawiasem kwadratowym – [,table]. Nie wiem, dlaczego ona tak wygląda, ale tak jest w oficjalnej dokumentacji, więc tego się będę trzymał.
Wracając do funkcji. Ona jedynie tworzy obiekt tekstowy, niczego nie wyświetla, ani nie wypisuje. Poza tym, co przypadkiem zdarzyło mi się odkryć, możemy stworzyć jeden obiekt i wyświetlić go wielokrotnie. Nie wiem czy takie wykorzystanie funkcji idzie w parze z wytycznymi poprawnego tworzenia skryptów w Hollywood, ale w tym wypadku działa i nic się nie kaszani.
W argumencie table, możemy określić:
Align= wyrównanie
#Left – do lewej (wartość domyślna)
#Right – do prawej
#Center – po środku
#Justified – równomierne rozłożenie – ten argument wymaga Hollywood w wersji 7.0!
WordWrap= szerokość w pikselach, na przykład 500
Encoding= system kodowania znaków
Color= kolor tekstu, musi być podany jako wartość ARGB, czyli w postaci $AARRGGBB
Tu muszę się podzielić następnym odkryciem, bo nieopisanym w dokumentacji; otóż jeśli określimy WordWrap, to tekst podany w argumencie tekst$ musi znajdować się na jednej linii w skrypcie, w innym wypadku interpreter wyświetli nam błąd: „Unterminated string!”; w wypadku krótkich tekstów to nie kłopot, ale w wypadku dłuższych może to się okazać problematyczne. Pewnie da się przekazać tekst jaki ma stworzyć nasza funkcja jako wskaźnik do pliku, z którego sama odczyta treść, ale my jeszcze tego nie potrafimy. Natomiast jeśli nie określimy WordWrap to tekst wyjedzie nam poza ekran jeśli będzie zbyt długi.
Zanim zaczniemy odnosić powyższe informacje do konkretnego przypadku naszej invitki, muszę jeszcze wspomnieć o tym, w jaki sposób Hollywood wyświetla obiekty na ekranie. Odnosi się to do wszystkich obiektów, jakie są dostępne w tym języku programowania.
Warstwowość
Jako że Hollywood to język skryptowy, to jest odczytywany linia po linii od góry do dołu, Amerykę w konserwach…
Przez co wszystko, co wyświetlimy, będzie „układane” jedno na drugim, czyli jeśli na początku wrzucimy sobie słowo „Cześć” na połowę strony, to nasze powitanie będzie w tle tego, co wyświetlimy później. Warto to wziąć pod uwagę, bo dopóki nie nauczymy się tworzyć warstw i nimi manipulować, nie mamy żadnej możliwości zmiany kolejności ich wyświetlania na ekranie.
Warstwami zajmiemy się, gdy pojawi się taka potrzeba, sama biblioteka rozkazów warstw jest tak duża, że mogłaby wypełnić kilka artykułów. A nie jest moim celem „przepisywanie” dokumentacji, więc najpewniej opiszę tylko te funkcję potrzebne do naszych celów.
Podsumowując: Hollywood będzie wyświetlał nasze obiekty na ekranie tak, jakbyśmy my kładli kolejne kartki papieru lub przeźrocza jedne na drugie.
Mając to na uwadze, możemy zacząć tworzyć nasze zaproszenie. Na początku mamy znajome funkcje, których po raz wtóry nie będę tu opisywał.
Ogólnie tylko pisząc, mamy tam określenie wymaganej wersji Hollywood, wielkości ekranu, koloru tła, bezramkowość okna i polecenie załadowania pięciu krojów czcionek do późniejszego użycia. (Zrzut 1).
Następnie przy pomocy funkcji UseFont ustawiamy aktualną czcionkę na Font „3” czyli Exo 2 Bold o wielkości 700 pikseli.
Zmieniamy kolor – SetFontColor, i włączamy wygładzanie – SetFontStyle(#ANTIALIAS). Gdy mamy już określone, jaką czcionką chcemy pisać, to możemy stworzyć obiekt tekstowy, który będzie nią pisany; w drugą stronę nie zadziała. Mam na myśli, że najpierw musimy określić czcionkę i jej cechy, a dopiero potem tworzyć obiekt tekstowy. Teraz wyświetlmy nasz obiekt na ekranie za pomocą:
DisplayTextObject(id,x,y)
Funkcja ta przyjmuje trzy argumenty. Pierwszy to identyfikator tekstu który chcemy wyświetlić, a x i y jak łatwo się domyślić to współrzędne na ekranie. Układ współrzędnych w Hollywood ma swój początek, czyli 0,0, w lewym górnym rogu ekranu. Przy tej okazji muszę wspomnieć o tym, że każdy obiekt ma punkt, który jest jego „uchwytem”; w Hollywood nosi on nazwę Anchor – kotwica, jest on zarazem osią obrotu.
Domyślnie jest on ustawiony na górny lewy róg niewidocznej ramki obramującej obiekt, która może przybierać kształt prostokąta.
Punkt uchwycenia można zmieniać, niestety nie można go przesunąć poza obręb obiektu, na przykład w punkt -1, -1, ale o tym przy innej okazji.
DisplayTextObject(3, 60, -50)
Liczba 3 w nawiasie to identyfikator naszego tekstu, który nadaliśmy mu przy tworzeniu go funkcją CreateTextObject (3, „#2”), teraz przesuwamy nasz napis 60 pikseli w prawo i 50 w dół.
Czyli do kodu widocznego powyżej dopisujemy kod jak na (Zrzut 2) i otrzymujemy rezultat jak na (Zrzut 2.1).
(Na zrzutach pokazuję dopisywany kod, cały listing – pod koniec artykułu).
Pokrótce tylko opiszę funkcję bardzo podobną do poprzedniej. Użycie jej w naszym skrypcie nie ma sensu, bo wynik jest nieruchomy, a funkcja ta określa efekt specjalny, z jakim na ekranie pojawiają się obiekty tekstowe.
DisplayTextObjectFX(id, x, y[, table])
Jak widać, jedyna różnica to dodatkowy atrybut [, table]. W bardzo dużym skrócie – jest to tablica opisująca, jaki efekt ma być użyty i z jaką prędkością.
Przejdźmy teraz do następnego elementu naszej invitki, a są to trzy rzędy obróconych pod kątem zielonych znaków „większy niż”.
Obracanie obiektów tekstowych odbywa się przy pomocy funkcji:
RotateTextObject(id, angle)
Składnia jest prosta, id to identyfikator obiektu tekstowego który chcemy obrócić, a angle to kąt o jaki obracamy. Wartość dodatnia obraca odwrotnie do wskazówek zegara, a ujemna zgodnie z nimi. Ważna uwaga odnośnie obracania czcionek: Hollywood nie potrafi jeszcze obracać czcionek wektorowych i przez to zmienia je na obiekt graficzny, dlatego musimy ustalić wszystkie cechy jakie chcemy nadać naszemu tekstowi przed obrotem, (ma się to zmienić, niestety w niekreślonej przyszłości). W wypadku czcionek wektorowych wiąże się to z utratą jakości, w przypadku bitmapowych oczywiście nie ma to znaczenia, bo już są pikselowe przed obrotem.
To do dzieła. Używamy czcionki z id 4, zmieniamy kolor na jakiś zielony – $D0E0D0, i tworzymy obiekt tekstowy „\t \t \t >>>”
Te trzy „\t” to trzy znaki tabulacji, które chcemy wstawić przed naszymi „ptaszkami” w celu przesunięcia osi obrotu poza obręb widocznej części obiektu tekstowego. Moglibyśmy użyć atrybutu AnchorX i Y, ale tak jak wspomniałem wcześniej, nie da się przesunąć punktu uchwycenia dalej niż sięga sam obiekt, a w tym wypadku to by nie wystarczyło. Stąd taka bandycka metoda wstawienia kilku białych znaków – czyli matki, potrzeby i wynalazki, czy jak tam to szło.
Pierwszy rząd „ptaszków” obracamy o 45 stopni, czyli z grubsza na dół i w prawo – RotateTextObject(4, -45), następnie musimy go wyświetlić, co czynimy przez
DisplayTextObject(4, #CENTER+250, #CENTER+180)
Wartości dobierałem metodą prób i błędów, zarówno jeśli chodzi o obrót jak i pozycję na ekranie. Napiszę tylko co to ten #CENTER+250 i 180, jest to pozycja dla wyświetlenia naszego obiektu tekstowego o id 4.
#CENTER to środek naszego okienka z invitką, a wartości 250 i 180 pikseli dodałem do automatycznie wyliczonego środka okienka. Zamiast wyliczać co do piksela wysokość i szerokość, dzielić na pół i dodawać powyższe wartości, zastosowałem taką metodę, stosowanie stałych
może ułatwić tworzenie programów niezależnych od rozdzielczości ekranów, na których są wyświetlane. Oczywiście trzeba by wtedy użyć wartości względnych w stosunku do wielkości naszego okna, czcionek i tak dalej, ale to zupełnie inna bajka.
O.K., w tym miejscu mamy już jeden rząd ptaszków na ekranie, teraz za pomocą RotateTextObject obracamy go jeszcze raz i wyświetlamy ponownie, i potem jeszcze raz to samo, oczywiście z innymi wartościami. Kod i wynik poniżej na zrzutach (Zrzut 3) i (Zrzut 3.1).
Zwróćcie uwagę na dwie rzeczy. Pierwsza to fakt że obiekt tekstowy został stworzony raz, a wyświetlony trzykrotnie. Druga to to, że obrót następuje zawsze od pozycji wyjściowej. W naszym wypadku stworzyliśmy jeden obiekt, obracaliśmy go kolejno o wymaganą liczbę stopni, czyli nie jest tak, że:
tworzymy –> obracamy –> wyświetlamy –> obracamy dalej, tylko:
tworzymy –> obracamy –> wyświetlamy –> obracamy od zera –> znowu wyświetlamy…
Następna część naszego skryptu technicznie nie różni się od poprzedniej. Wybieramy czcionkę, ustawiamy kolor, włączamy wygładzanie, tworzymy obiekt tekstowy „CZEŚĆ”, nadajemy mu identyfikator 1, dodając równomierne rozłożenie (#JUSTIFIED) na odcinku pięciuset pikseli (WordWrap=500).
Następnie obracamy o 90 stopni i wyświetlamy po prawej stronie na środku, używając stałych #RIGHT-20, #CENTER. Kod i efekt na zrzutach (Zrzut 4) i (Zrzut 4.1).
Przyszedł czas na główny tekst zaproszenia, czyli szpalta literek po lewej stronie na pierwszym planie. Tu nie będę się rozpisywał, bo poza jedną rzeczą nie ma dla nas nic nowego. Kod i zrzut poniżej, podpisane jako (Zrzut 5) i (Zrzut 5.1).
Jedyną rzeczą, którą już opisywałem w poprzedniej części, jest formatowanie tekstu „w locie”. W naszym wypadku zmieniłem kolor gwiazdki odniesienia na czerwony tagiem formatującym
[COLOR=#RED]*[/COLOR]
w tekście przekazywanym jako argument text$, funkcji CreateTextObject. Poza tym, tak jak już wspominałem wyżej, cały tekst musi się znajdować na jednej linii skryptu.
W końcu ostatni element zaproszenia, którym jest tekst wyjaśniający po gwiazdce na samym dole okienka. Tu nie ma już zupełnie nic nowego dla nas, więc rozkminienie pozostawiam Wam. Kusiło mnie natomiast żeby zastosować inną funkcję do wyświetlenia tego tekstu, a mianowicie TextOut, ale ta niepozornie wyglądająca funkcja to gigant jeśli chodzi o możliwości; ma oczywiście swoje ograniczenia, ale w zależności od potrzeb może zastąpić CreateTextObject i DisplayTextObject jednocześnie, obiec je dwa razy w koło, zdrzemnąć się, a tamte dwie i tak wciąż będą z tyłu. Dlatego opiszę ją na końcu.
Zrzuty z ostatnią częścią invitki: (Zrzut 6) i (Zrzut 6.1), czyli cały kod zawarty w lekcji i efekt końcowy.
Żeby dopełnić opis funkcji manipulujących tekstem opiszę kilka funkcji, które mogą nam się przydać w przyszłości.
[id] = CopyTextObject(source, dest)
Funkcja ta kopiuje obiekt tekstowy „source”, który musimy podać jako identyfikator do źródłowego obiektu tekstowego, masło maślane, do innego obiektu tekstowego, który musimy podać jako identyfikator w miejsce „dest”. Możemy zdać się na Hollywood, i nie podawać identyfikatora docelowego, i zamiast niego użyć NIL; wtedy zostanie automatycznie przydzielony identyfikator, i zwrócony jako wynik działania funkcji do [id], które to musimy określić.
Na przykład
CreateTextObject(1, „Tekst do sklonowania”)
DisplayTextObject(1, 20, -10)
sklonowany = CopyTextObject(1, NIL)
DisplayTextObject(sklonowany, 20, -100)
stworzy nam obiekt tekstowy „Tekst do sklonowania” wyświetli go 20 pikseli od lewej strony i -10 pikseli od góry, skopiuje go i wyświetli 20 pikseli od lewej strony i -100 pikseli od góry. Ograniczeniem tej funkcji jest to, że klon nie poddaje się żadnym próbom zmiany wyglądu – będzie wyglądał tak jak oryginał. Można oczywiście klona obracać, przesuwać itp. Szczerze pisząc, nie wiem jakie może być zastosowanie tej funkcji, wydaje się dawać mało korzyści w stosunku do narzucanych ograniczeń, ale jestem przekonany, że jest jakiś dobry powód jej istnienia, tylko jeszcze o nim nie wiem ; ).
Bez kombinacji z autoprzydzielaniem identyfikatorów to samo co wyżej będzie wyglądać tak:
CreateTextObject(1, „Tekst do sklonowania”)
DisplayTextObject(1, 20, -10)
CopyTextObject(1, 2)
DisplayTextObject(2, 20, -100)
FreeTextObject(id)
Ta funkcja uwalnia nam obiekt tekstowy z pamięci, dzięki czemu możemy ją oszczędzić na coś bardziej akurat potrzebnego ;D. Przykład:
CreateTextObject(1, „Tekst do sklonowania”)
FreeTextObject(1)
MoveTextObject(id, xa, ya, xb, yb[, table])
Przesuwa obiekt tekstowy o identyfikatorze „id” z punktu „a” do punktu „b”; „a” i „b” to koordynaty w pikselach. Poza tym opcjonalnie w tablicy możemy określić z jaką szybkością ma następować przesunięcie, czy chcemy zastosować efekt specjalny towarzyszący zmianie pozycji, i w końcu czy przesunięcie ma być asynchroniczne. Nie będę tego zgłębiał teraz, ale jeśli was to ciekawi to możecie poczytać o tym pod adresem:
www.hollywood-mal.com/docs/html/hollywood/MoveBrush.html
ScaleTextObject(id, width, height)
Funkcja ta skaluje obiekt tekstowy określony identyfikatorem id do pożądanych rozmiarów. Jeśli nasz tekst jest pisany czcionką wektorową to nie nastąpi utrata jakości. Jako width albo height możemy podać stałą wbudowaną #KEEPASPRAT (od Keep Aspect Ratio – zachowaj proporcje) wtedy rozmiar zostanie obliczony automagicznie. Width i height mogą zostać podane jako liczby albo procenty. Przykłady:
ScaleTextObject(1, 200%, #KEEPASPRAT) – powiększy tekst wszerz dwukrotnie i automatycznie dopasuje wysokość zachowując proporcje.
ScaleTextObject(1, #KEEPASPRAT, 500) – zmieni wysokość obiektu tekstowego do 500 pikseli i dopasuje automatycznie szerokość.
TextOut(x, y, text$[, table])
Funkcja ta wypisuje tekst przekazany w argumencie „text$” w pozycji określonej przez x i y, podobnie jak w przypadku DisplayTextObject współrzędne możemy podawać jako liczby albo stałe wbudowane. a tekst może być formatowany w locie poprzez użycie tagów formatujących jak [I][/I], [COLOR][/COLOR] itd. W argumencie [, table] przekazujemy atrybuty podobnie jak w CreateTextObject, ale oprócz nich możemy jeszcze użyć
StandardDrawTags.
Poczytacie o nich więcej tu:
www.hollywood-mal.com/docs/html/hollywood/StandardDrawTags.html
Jak zaraz zobaczycie, funkcja ta łączy w sobie możliwości Display/CreateTextObject, i dodaje jeszcze kolejne.
Należy jednak pamiętać że część opcji wymaga włączenia warstw.
Kod i efekt na zrzutach (Zrzut 7) i (Zrzut 7.1). Jak widać są całkiem spore możliwości.
I tym kończymy drugi odcinek. Zapraszam na następny, w którym postaram się w twórczy sposób wykorzystać to, co już umiemy i dodać nowe rzeczy.
’ferin’ – Amiga NG (2) 1/2018