[#1] Wyswietlanie tekstu w oknie
Cześć,
Znów podpinam pod blitz-a ale raczej pytanie jest ogólne.
Wiem już jak napisać coś w oknie przy pomocy Text i Move, ale to trochę mało.
Jako że czytam i przeglądam inne tematy w tym samym czasie to podejrzewam że zajmie mi to zbyt długo by samemu to rozgryzc.

Pytanie moje jak podejść do wyświetlenia np pliku textowego z 10 tys znaków?
Czy ja musze pisać go do jakiejś bitmapy a potem wkleić w okno i zadbać o gadżety scroll-i?
Jeśli tak, to potem w zależności od pozycji scroll-a wyświetlać odpowiedni fragment bitmapy?

Wybaczcie jeśli prostackie pytanie ale zaczynam tu od zera i chciałbym tym razem szybciej ruszyć.

Dodano.
Potrzebuję tylko wskazówki w jakim kierunku patrzeć.
Posciagalem autodock-i a tam czytania jest dużo...

Ostatnia aktualizacja: 06.08.2018 20:37:50 przez peceha
[#2] Re: Wyswietlanie tekstu w oknie

@peceha, post #1

Pytanie moje jak podejść do wyświetlenia np pliku textowego z 10 tys znaków?
Czy ja musze pisać go do jakiejś bitmapy a potem wkleić w okno i zadbać o gadżety scroll-i?
Jeśli tak, to potem w zależności od pozycji scroll-a wyświetlać odpowiedni fragment bitmapy?

Najlepiej w przypadku dużego tekstu nie alokować dużej bitmapy, tylko odświeżać tekst na bieżąco.

Oryginalne graphics.library ma pomocnicze funkcje do wyświetlania tekstu:
- ClearEOL(), który czyści RastPort aż do końca linii (End Of Line),
- ClearScreen(), który czyści resztę RastPortu na prawo i w dół.

Uwaga: te funkcje najlepiej radzą sobie z oknami typu GimmeZeroZero lub bez ramki.

Jeśli chcesz wyświetlić tekst, musisz go jakoś przechować. Najlepiej skorzystać z jedno- lub dwukierunkowej listy kolejnych linii.

Żeby wyświetlić tekst np. od 5 linijki to maszerujesz wzdłuż listy aż dojdziesz do 5-tego elementu (koszt zależy od liczby linii). Następnie wyświetlasz ten tekst w oknie. Jak chcesz kolejne linie narysować robisz ClearEOL(), ustawiasz na początek nowej linii za pomocą Move() i rysujesz tekst.

Jeśli jest to ostatnia linijka, którą chcesz wyświetlić robisz ClearScreen().

Atutem przechowywania tekstu w liście linii jest stały koszt dodawania i usuwania linijek.

Jeszcze wskazówka: jak chcesz błyskawicznie wyświetlić tekst skorzystaj z funkcji SetWriteMask() i ustaw jeden bitplan. Taki tekst jest bardzo szybko skrolowany nawet w dużym oknie.

Warto podczas rysowania nie korzystać z RastPortów, które posiadają Layer. Blokowanie Layera i przycinanie (Clipping) jest kosztowne. Zatem wszystkie pośrednie funkcje rysujące rób na RastPorcie bez Layera.

Rada: skorzystaj z funkcji DoHookClipRects() w przypadku RastPortów z Layerem. Jest to funkcja bardziej zaawansowana, ale pozwala na bezpośredni dostęp do BitMapy - składowych części warstwy (Layer), np. okienka.
[#3] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #2

jak chcesz błyskawicznie wyświetlić tekst skorzystaj z funkcji SetWriteMask() i ustaw jeden bitplan.
To zadziała tylko gdy kolor tekstu (numer w palecie) będzie potęgą dwójki.
[#4] Re: Wyswietlanie tekstu w oknie

@Krashan, post #3

To zadziała tylko gdy kolor tekstu (numer w palecie) będzie potęgą dwójki.

Zgadza się. W domyśle chodziło mi o kolor czarny - nr 1 w palecie.
[#5] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #4

No super. Dzięki serdeczne.
Nawet nie liczyłem na tyle wskazówek!! - Dużo czasu mi to zaoszczędzi.

OK
[#6] Re: Wyswietlanie tekstu w oknie

@peceha, post #5

Jeszcze nawiązując do uwagi kolegi Krashana, dodam że jak chcesz wyświetlić tekst w kolorze, to SetWriteMask() ustaw na tyle bitplanów ile potrzeba. Np. jak korzystasz z barw 0, 1, 2 i 3 to ustawiasz na 3. Funkcja ta przydaje się w optymalizowaniu rysowania w ogólności.

Zaś jeśli za jednym razem chcesz zmienić wiele parametrów RastPortu skorzystaj z funkcji SetRPAttrsA(). Działa ona szybciej niż wywoływanie pojedyncze dla każdego parametru (np. SetAPen(), SetBPen(), SetDrMd(), SetWriteMask() itp.).
[#7] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #6

Zanotowane OK
[#8] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #2

Czesc, wracam do tego (a wlasciwie dopiero sie za to zabieram, byla dluga kolejka innych tematow).

Mam kilka pytan, ktore moga wydac sie banalne ale mysle ze tak szybciej dostane potrzebne informacje (chodzi o zrozumienie gdzie ja wogole jestem szeroki uśmiech ).

1. napisales by nie alokowac duzej bitmapy
Z tego co widze to bitmapa jest tworzona zawsze gdy powstaje nowy ekran (RastPort\BitMap) i jesli dobrze zrozumialem dokumentacje to pointer w strukturze Window wskazuje na te sama bitmape - wiec troche jestem skolowany tym "tworzeniem (wlasnej?)" bitmapy.

Tutaj zdjecie z mojego rogramu. Wyswietlane informacje pochodza ze struktury WINDOW\RPort\BitMap. (czyli jakias bitmapa juz jest)

Tak przy okazji: do czego jest pozycja "pad"??

2. podales komendy, ktore czyscza RAstPort (a nie BitMape?) - wydawalo mi sie ze rastport to tylko informacje definiujace jak i gdzie operacje graficzne moga sobie "poszalec" (chociaz opis komendy np: ClearScreen(), faktycznie mowi o czyszceniu rastport-u)

Dzieki
[#9] Re: Wyswietlanie tekstu w oknie

@peceha, post #8

1. napisales by nie alokowac duzej bitmapy
Z tego co widze to bitmapa jest tworzona zawsze gdy powstaje nowy ekran (RastPort\BitMap) i jesli dobrze zrozumialem dokumentacje to pointer w strukturze Window wskazuje na te sama bitmape - wiec troche jestem skolowany tym "tworzeniem (wlasnej?)" bitmapy.

Ja polecałem Ci tylko nie alokować wielkiej bitmapy na cały obszar z tekstem, tylko odświeżać go na bieżąco.

Okienko, jak można przeczytać w dokumentacji, może mieć jeden z trzech rodzajów odświeżania:

  • SIMPLE REFRESH - Wówczas okienko korzysta z bitmapy ekranu i musi zawsze odświeżać odsłaniane miejsca. Wtedy oszczędzasz na pamięci graficznej.
  • SMART REFRESH - Wówczas okienko posiada własną bitmapę o wielkości okna i nie trzeba odświeżać odsłanianych miejsc, ale trzeba odświeżać, gdy zwiększymy rozmiar okienka.
  • SUPER BITMAP - Wówczas okienko ma podpiętą własną bitmapę, która może być większa niż okno i nie trzeba w ogóle odświeżać, nawet gdy zwiększymy rozmiar okienka.


Tak przy okazji: do czego jest pozycja "pad"??

To jest pole o rozmiarze bajta, które tylko dosuwa elementy struktury do adresów parzystych.

(Na marginesie to wiem, że akurat system wykorzystuje wartość w pad BitMapy. Jeśli jest tam pewna określona stała liczba, to bitmapa jest typu Interleaved. Ale to nie jest zasada! Pad ma tylko dosuwać do wartości parzystej)

2. podales komendy, ktore czyscza RAstPort (a nie BitMape?) - wydawalo mi sie ze rastport to tylko informacje definiujace jak i gdzie operacje graficzne moga sobie "poszalec" (chociaz opis komendy np: ClearScreen(), faktycznie mowi o czyszceniu rastport-u)

Rzeczywiście masz rację, one czyszczą BitMapę wskazywaną przez ten RastPort. RastPort przechowuje pewne dodatkowe informacje, jakie prostokąty objąć operacją, jakiego użyć koloru ołówka itp.
[#10] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #9

Dzieki !!

Nawet jakbym bardzo chcial i przeczytal cala dokumentacje 10x to i tak nic by to nie dalo.
Najwyrazniej lepiej mi sie to przyswaja "po trochu" - na zasadzie co mi akurat jest potrzebne.
Np fragment o sposobie odswiezania okien widzialem milion razy i ... milon razy go pomijalem bo na tamta chwile bylo mi to zbedne szeroki uśmiech
[#11] Re: Wyswietlanie tekstu w oknie

@peceha, post #10

Ja też. W moim wypadku np. od dawna chcę się nauczyć True Requesterów i BOOPSI ale do tej pory nie potrafię. Nadal nie wiem jak z nich korzystać. Również nie potrafię zapamiętać kolejności wszystkich pól w strukturach NewScreen, czy NewWindow, dlatego wolę listy tagów.
[#12] Re: Wyswietlanie tekstu w oknie

@peceha, post #8

W istocie sam RastPort jako taki danych graficznych nie zawiera, bo zawiera je jego bitmapa. Tak jak piszesz jest to zbiór informacji opisujący jak i gdzie pracują operacje graficzne. Sformułowanie „wyczyścić RastPort” to skrót myślowy oznaczający w praktyce wyzerowanie odpowiedniego fragmentu odpowiedniej bitmapy. Jaki to jest fragment, jakiej bitmapy i jak to najlepiej wyczyścić, to już ogarnia system operacyjny.
[#13] Re: Wyswietlanie tekstu w oknie

@peceha, post #1

Najwyrazniej ciagle czekam na wene szeroki uśmiech bo jeszce nie zaczalem ale i tak juz mam kolejne pytania:

-przewijanie
zakladam ze to wszystko musze zrobic recznie?
czyli na starcie wczytac caly plik (a przynajmniej policzyc ile ma lini),
stworzyc gadget typu SCROLLER_KIND i odpowiednio skonfigurowac (na podsatwie kroku wyzej),
wyswietlac linie na ktore "wskazuje" SCROLLER

Czyli kazde przesuniecie "scroller-a" (czy to strzalkami przewiniecie tekstu czy myszka klikajac na belke) wiaze sie z wyczyszczeniem bitmapy i ponownym wypisaniu na niej odpowiednich lini?

Dobrze to rozumuje?
[#14] Re: Wyswietlanie tekstu w oknie

@peceha, post #13

Nie każde przesunięcie scrollera musi oznaczać całkowite odświeżenie okna. Jeżeli wyliczysz, że część "starych" linii pozostanie wciąż w oknie, to możesz użyć funkcji ScrollWindowRaster() do przesunięcia ich we właściwe nowe miejsce, a wyrysować tylko nowo pojawiający się tekst.
[#15] Re: Wyswietlanie tekstu w oknie

@Krashan, post #14

Dzieki za informacje.
Zabieram sie za to jak pies do jeza ..
[#16] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #2

Warto podczas rysowania nie korzystać z RastPortów, które posiadają Layer. Blokowanie Layera i przycinanie (Clipping) jest kosztowne. Zatem wszystkie pośrednie funkcje rysujące rób na RastPorcie bez Layera.

Sorry ze tak "zawracam gitare" ale czegos tu nie rozumiem. Otwierajac okno mam automatycznie tworzony Layer, tak?
Byc moze pytam o sprawy oczywiste ale ja tu wciaz bladze :)
Wiec o co chodzi z tym rast portem bez layera?

Wczesniej napisales, ze podane przez Ciebie komendy najlepiej sobie radza z oknami GIMMEZEROZERO lub bez ramki. Dzis czytajac "male co nieco" wpadlo mi w oko (czesc pogrubiona i podkreslona):
WA_GimmeZeroZero
Set this tag to create a GimmeZeroZero window. GimmeZeroZero windows have the window border and border gadgets rendered into an extra layer. This extra layer slows down window operations, thus it is recommended that applications only use GimmeZeroZero windows when they are required. For clipping graphics to the area within the borders of a window, see the discussion of "Regions" in Layers Library. Equivalent to NewWindow.Flags WFLG_GIMMEZEROZERO


Wiec to chyba sam musze sie przekonac co bedzie dla mnie lepsze: poprawne (szybkie) dzialanie tych komend czy szybsze reagowanie programu.

Dzieki !!
I czekam na dalsze wyjasnienia bo sa one bardzo pomocne OK
[#17] Re: Wyswietlanie tekstu w oknie

@peceha, post #16

Otwierajac okno mam automatycznie tworzony Layer, tak?

Tak.

Wiec o co chodzi z tym rast portem bez layera?

Chodzi o to, że każda operacja na RastPorcie okienka (składowa RPort) jest przycinana do warstwy okna, co jest operacją kosztowną. Lepiej renderować pośrednio przez BitMapę bez Layera i dopiero na koniec skopiować wynik do okna.

Można to zrobić w ten sposób, że inicjujesz własny RastPort, który pole Layer będzie miał ustawione na NULL i wówczas operacje na tym RastPorcie będą szybsze.

Jedna uwaga: operacje będą szybsze ale bardziej niebezpieczne, gdyż łatwiej zaśmiecić pamięć graficzną nie należącą do BitMapy.

Inicjujesz taki RastPort za pomocą InitRastPort (uwaga struktura RastPort musi być zadeklarowana statycznie albo zaalokowana, deklaracja wskaźnika nie wystarczy).

Następnie zaalokuj bitmapę o dowolnej głębi barw, wielkości wnętrza okienka (składowe GZZWidth i GZZHeight) i podepnij pod ten RastPort. Następnie rysuj tekst na tym RastPorcie, po czym skopiuj zawartośc tej BitMapy do okna już za pomocą operacji uwzględniającej Layer (np. BltBitMapRastPort), albo używając tej zaawansowanej funkcji DoHookClipRects().

Wiec to chyba sam musze sie przekonac co bedzie dla mnie lepsze: poprawne (szybkie) dzialanie tych komend czy szybsze reagowanie programu.

A faktycznie, zapomniałem o regionach. Tak, zastosuj się do tej rady. Regiony to obszary wewnątrz warstw, do których przycinana jest grafika. Utwórz region wielkości wnętrza okienka, podepnij za pomocą InstallClipRegion() i rysuj. Wtedy wszystko co wypadnie poza regionem zostanie przycięte.

Jeszcze ważna sprawa: rysowanie w okienka jest dosyć wolną operacją. Dlatego gorąco polecam skorzystać z tej funkcji DoHookClipRects(), która robi to bardzo szybko, bo właśnie rysuje bezpośrednio w BitMapę bez pośrednictwa Layera. Ale jest to funkcja, z której trudniej korzystać.

Możesz też po nabraniu wprawy, napisać własną, szybszą funkcję rysującą, uzupełniającą funkcje rysujące, jeżeli okaże się że potrzebujesz większą wydajność grafiki.

Ostatnia aktualizacja: 19.09.2018 18:56:54 przez Hexmage960
[#18] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #17

No i wyglada na to ze wiem juz wszystko by to ruszyc!
Podales wszystko jak na talerzu OK

Dzieki wielkie.
[#19] Re: Wyswietlanie tekstu w oknie

@peceha, post #18

Jak moge zdobyc rozmiar gadgetu do zmiany rozmiaru okna?
Szerokosc prawej ramki okna przyjmie szerosc tego wlasnie gadgetu - na te chwile ma to ustawione na zasadzie prob i bledow.

Ten moj scrollbar chyba jest jakis taki... nie bardzo
- ramke po lewej i prawej ma 2x grubsza
- nie ma tego ladnego "zakratkowania" w miejscu gdzie nie ma suwaka
- co nie wstawie w ustawieniach PGA_NewLook, PGA_Borderless, GA_RightBorder to wyglada na to ze moj program ma to w d...

By go zrobic uzylem komendy NewObjectA() i wynik wstawilem do okna do FirstGadget - tu raczej problemu byc nie powinno.



Ostatnia aktualizacja: 08.10.2018 21:25:20 przez peceha
[#20] Re: Wyswietlanie tekstu w oknie

@peceha, post #19

Jeśli chodzi o szerokość tego gadżetu do zmiany rozmiaru okna, to jest on równy rozmiarowi prawej ramki okna. Pobierzesz ten rozmiar z pola window->BorderRight struktury Okna, lub screen->WBorRight struktury Ekranu.

Pamiętaj, że szerokość (i wysokość) ramek dostosowuje się do rozmiaru gadżetów w nich umieszczonych.

Co do tej kratki, to poeksperymentuj z różnymi opcjami.

Ostatnia aktualizacja: 08.10.2018 21:33:00 przez Hexmage960
[#21] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #20

Nawet mi do glowy to nie przyszlo.
Caly czas myslalem ze WBorLeft i WBorRight i WBorBottom maja standartowa szerokosc ramki "bez gadget-ow" (no ale wlasciwie jesli tak by mialo byc to wystarczyla by jedna zmienna a nie 3 , hehe )

Dzieki.
[#22] Re: Wyswietlanie tekstu w oknie

@peceha, post #21

Tylko w przypadku górnej ramki, do WBorTop należy dodać wysokość czcionki + 1. Reszta przybiera rozmiar standardowych gadżetów.

Chyba, że coś pomyliłem. Jeśli tak, to przepraszam.

Sprawdzę u siebie.

Ostatnia aktualizacja: 08.10.2018 21:43:21 przez Hexmage960
[#23] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #22

Nie ma to za wiele wspolnego z tematem ale jak najbardziej jest zwiazane z tym co chce zrobic.

Jak dostac informacje na jakiej rozdzielczosci ekranu jest otwarte okno?
Chodzi mi o typ: LOWRES, MEDRES, HIRES niz o rozdzielczosc pozioma/pionowa.
Chcialbym by okno automatycznie dobieralo rozmiar systemowych gadgetow w zaleznosci od "typu" rozdzielczosci (ustawiajac odpowiednia wartosc w polu "SYSIA_Size" dla obrazkow gadgetow systemowych).

Dzieki

Dodalem:
@Hexmage960
Co do szerokosci ramki to wyglada ze wartosc pobrana ze Screen->WBorRight/Left nie uwzglednia gadgetow.
Znalazlem ze rozmiar gadgetu "resize" mozna dostac np tak (ustawiajac potrzebny typ rozdzielczosci w SYSIA_Size):
sizeimage = NewObject (NULL,SYSICLASS,
			SYSIA_Which,SIZEIMAGE,
			SYSIA_Size,SYSISIZE_MEDRES,
			SYSIA_DrawInfo,drawinfo,
			TAG_END);
		if (sizeimage)
			{
			GetAttr (IA_Width,sizeimage,&sizew);
			GetAttr (IA_Height,sizeimage,&sizeh);
			}



Ostatnia aktualizacja: 10.10.2018 11:36:55 przez peceha
[#24] Re: Wyswietlanie tekstu w oknie

@peceha, post #23

Co do rozdzielczości to szukasz tzw. Aspect Ratio.

Pod systemem 2.0+

Korzystasz z funkcji GetDisplayInfoData() z graphics.library (opis).

Podając jej za parametry:
handle: NULL,
buf: wskaźnik na zadeklarowaną statycznie strukturę DisplayInfo,
size: sizeof(struct DisplayInfo),
tagID: DTAG_DISP,
ID: identyfikator tego trybu ekranu (np. LORES_KEY).

W rezultacie otrzymasz garść informacji o tym trybie ekranu w tej strukturze i znajdziesz w niej Aspect Ratio w polu Resolution, który jest typu Point, czyli:
Resolution.X,
Resolution.Y.

Przykład: Aspect ratio dla LORES jest X=44, Y=44, a dla HIRES jest X=22, Y=44.
Na tej podstawie możesz obliczać wielkość przycisków.

Więcej informacji (w tym wzór matematyczny na obliczanie rozmiarów na podstawie Aspect Ratio) znajdziesz na Amiga Developer CD: Carolyn Sheppner napisała cały artykuł o tym w Amiga Mail vol. 2.

Co do szerokosci ramki to wyglada ze wartosc pobrana ze Screen->WBorRight/Left nie uwzglednia gadgetow.

Rozumiem. Fajnie to rozwiązałeś pobierając atrybuty za pomocą GetAttr().
[#25] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #24

Dzieki za informacje.
[#26] Re: Wyswietlanie tekstu w oknie

@peceha, post #25

Wow, ile to czasu uplynelo ale jednak wrocilem do tematu i ...
oto dzialajaca ListView wlasnej roboty w blitzie :)



PS.
jak namalowac "pattern" na bitmapie? np. zakratkowanie by pokazac ze obszar jest aktualnie nieaktywny?
Dzieki
[#27] Re: Wyswietlanie tekstu w oknie

@pch, post #26

Brawo, ten ListView wygląda rewelacyjnie. OK

Tak się składa, że wczoraj też opracowałem własny ListView - na potrzeby mojej gry.

Teraz sprawiam, żeby suwaczek pracował w podwójnym buforowaniu. Używam do tego swojej klasy BOOPSI.

jak namalowac "pattern" na bitmapie? np. zakratkowanie by pokazac ze obszar jest aktualnie nieaktywny?

Patterny obszarowe masz pod makrem w <graphics/gfxmacros.h> SetAfPt(rp, pat, n), gdzie rp to RastPort, pat to tapeta w pamięci CHIP o szerokości 16 pikseli (bitów), zaś n to logarytm o podstawie 2 z wysokości, tzn. wysokość musi być potęgą dwójki:

n(1) = log2(1) = 0
n(2) = log2(2) = 1
n(4) = log2(4) = 2
n(8) = log2(8) = 3

Przykład: tapeta kratka to:

Pattern: 0x5555, 0xAAAA (wartości szesnastkowe).

SetAfPt(rp, pattern, 1).
[#28] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #27

Dzieki za informacje,
pewnie bym szukal i szukal ...
OK

ps.
to wlasciwie do czego jest BltPattern() ?

Ostatnia aktualizacja: 04.01.2022 09:20:05 przez pch
[#29] Re: Wyswietlanie tekstu w oknie

@pch, post #28

to wlasciwie do czego jest BltPattern() ?

Przyznam, że czytałem kiedyś o tej funkcji, ale nie używałem.

Teraz czytam i faktycznie, przyda się jeszcze lepiej do tego co potrzebujesz - czyli zamazać tylko niektóre piksele.

Przygotuj zatem maskę w ten sam sposób: 0x5555, 0xAAAA ale tym razem o wysokości obszaru, który chcesz zmodyfikować.

Uwaga: Być może maska używana przez systemowe wyszarzanie jest rzadsza, tzn. bity są bardziej oddalone - np. 0x1111, 0x0000, 0x4444, 0x0000.

Dzięki BltPattern() tylko i wyłącznie piksele określone w masce zostaną zmodyfikowane. Dzięki temu możesz stworzyć efekt wyszarzenia wybranych pikseli.

Kolor nanoszony ustalasz przez FgPen, czyli funkcją SetAPen().

Ostatnia aktualizacja: 04.01.2022 09:52:52 przez Hexmage960
[#30] Re: Wyswietlanie tekstu w oknie

@Hexmage960, post #29

Jak zwykle :) wielkie dzieki OK
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem