Tvorba okna na Sinclairu QL

Sinclair QL má multitasking a okna.

Jejich používání, notabene z Basicu, ale není úplně nejpřímočařejší.

Zvlášť po příchodu myší ovládaného okenního prostředí, kde by měl uživatel okno rád nejen jako pevně definovanou oblast obrazovky, ale jako oblast, kterou může nejlépe myší posouvat či měnit její velikost.

Systém toto ovšem neřeší, ten jen poskytne okenního manažera a očekává, že záležitosti s okny si bude řešit aplikace sama.

Pokud tedy okno v Basicu nechcete mít klasicky nepohyblivé a neměnné, musíte se o jeho přesuny a změny velikosti sami starat.

Změna nastavení okna z Basicu povelem WINDOW sice počítači řekne, že bylo okno předefinováno, ale pokud to nedoprovodíte parametry pro vykreslení rámečku okna (border, dostupné v Minerva a Thor ROM), na obrazovce se to nijak graficky neprojeví, vykreslené okno zůstane tam, kde je, jeho obsah se nepřesouvá.

Do nové oblasti se sice vypisuje či vykresluje nový výstup, ale ta se automaticky předem nesmaže, pokud to neuděláte příkazem CLS.

To neplatí pro aplikace pro Pointer Environment, které se o změnu polohy a velikosti okna mohou starat samy, na jejich zavolání se pak systém, respektive manažer oken, postará o smazání staré pozice a aplikace vykreslí obsah okna na nové místo nebo v nové velikosti.

Okenní prostředí Pointer Environment počítá s programováním v assembleru, případně lze jeho služby využívat programech psaných v C, z Basicu to ale jednoduché nebylo.

Tony Tebby, autor, tedy s přišel s QPTR, knihovnou, která rozšiřuje Basic o možnost práce s okenním manažerem.

Protože je ale Tony Tebby tak trochu mimozemšťan a věci si dělá možná lepším, ale rozhodně neobvyklejším způsobem, než jak to mají jiné systémy, není to úplně jednoduše použitelné či snadno pochopitelné.

Trochu se to snažil napravit Wolfgang Lenerz svým jedenáctidílným seriálem v časopise QL Today.

(Aby se programy používající služby okenního manažera daly kompilovat kompilátorem Turbo, existuje knihovna TurboPTR, která QPTR, které je naopak kompatibilní s kompilátorem QLiberator, pro tento účel víceméně nahrazuje.)

Pro “normální lidi” vzniklo ještě jedno rozšíření, EasyPTR, které má pomoci využívat QPTR méně mimozemským způsobem, například tím, že poskytuje WYSIWYG editor.

Pro to, abyste si pak v Basicu vytvořili okno, které se bude umět přesouvat a zavírat, pak postačí následující krátký prográmek (je pro snazší pochopení komentovaný).

(Adjektivum “krátký” může v tomto kontextu působit ironicky.)

Na obrázku vidíte tři okna vytvořená tímto prográmkem (další dvě okna patří editoru QD, jedno Basicu a jedno souborové utilitě Files).

Jistě si všimnete, že je v programu definována i jedna nepoužitá ikona.

8000 open#0,"con_": SP_JOBPAL -1,1 : initialise
8010 DR_PPOS#0,main_defn,-1,-1,m_lflg%
8020 Repeat Loop
8030 RD_PTR main_defn,it%,swnum%,event%,xrel%,yrel%,m_lflg%,0
8040 IF it%=1 : DR_UNST main_defn : CLOSE #mvch : STOP
8050 IF it%=0 : CH_WIN main_defn
8060 END REPeat loop
8070 :
8080 DEFine PROCedure Initialise
8090 :
8100 : REMark Define a general-purpose moveable channel &
8110 REMark a channel to cover the menu information window
8120 : REMark and some useful colours.
8130 :
8140 mvch%=FOPEN(con_) : REMark spare channel for embellishing
8150 :
8160 REMark Window Colours from chosen system palette
8170 scrollarrow=547 : between=560 : infoink=518
8180 stdink=514 : selectink=542 : selectstrip=541
8190 wndopapr=513 : wndobrdr=1024 : wndobg=533
8200 subbrdr=1219 : bgndppr=535
8210 :
8220 : REMark Possible item type codes: retx is added to return
8230 : REMark when hit, with (retr) or without (retn) a re-draw
8240 :
8250 text=0:sprite=2:blob=4:pattern=6
8260 retr=256:retn=-256
8270 hit$=CHR$(1):do$=CHR$(2):cancel$=CHR$(3):null$=""
8280 help$=CHR$(4):move$=CHR$(5):size$=CHR$(6)
8290 :
8300 REMark l(oose) x s(ize) l(oose) y s(ize)
8310 lxs=6*5:lys=12 : REMark size of 6 char loose items
8320 MainXsize=180 : MainYsize=84 : REMark calc values from application
8330 REMark bordsz=36
8340 :
8350 : REMark The initialisation of the menu itself starts
8360 : REMark here: this corresponds to a call to WM.SETUP
8370 :
8380 : REMark The standard window attributes
8390 :
8400 RESTORE 5390
8410 DIM std_wattr%(3)
8420 RD_WATT std_wattr%
8430 DATA 0,1,scrollarrow,wndopapr
8440 :
8450 : REMark Application sub window attributes
8460 DIM app_wattr%(3)
8470 RD_WATT app_wattr%
8480 DATA 0,1,subbrdr,bgndppr
8490 :
8500 : REMark The standard item attributes
8510 :
8520 DIM std_iattr(3,3)
8530 RD_IATT std_iattr
8540 DATA 1,stdink
8550 DATA wndopapr,wndobrdr,0,0
8560 DATA wndopapr,stdink,0,0
8570 DATA wndobrdr,stdink,0,0
8580 :
8590 DIM alt_iattr(3,3)
8600 RD_IATT alt_iattr
8610 DATA 1,subbrdr
8620 DATA wndopapr,wndobg,0,0
8630 DATA bgndppr,stdink,0,0 : REMark paper & ink colours
8640 DATA selectstrip,selectink,0,0 : REMark selected paper & ink
8650 :
8660 : REMark The data for the pointers
8670 :
8680 main_sprite=RD_SPRT
8690 DATA 6,5,4
8700 DATA ' www '
8710 DATA ' waw '
8720 DATA ' waw '
8730 DATA ' waw '
8740 DATA 'wwwwwa awwwww'
8750 DATA 'waaaa aaaaw'
8760 DATA 'wwwwwa awwwww'
8770 DATA ' waw '
8780 DATA ' waw '
8790 DATA ' waw '
8800 DATA ' www ',''
8810 :
8820 move_sprite=RD_SPRT
8830 DATA 5,4,4
8840 DATA 'aaaaaaaaaa '
8850 DATA 'awwwwwwwwa '
8860 DATA 'awwrrrrwwa '
8870 DATA 'awwrrrrwwaaaaa'
8880 DATA 'awwrrwwwwwwwwa'
8890 DATA 'awwwwwwwwrrwwa'
8900 DATA 'aaaaawwrrrrwwa'
8910 DATA ' awwrrrrwwa'
8920 DATA ' awwwwwwwwa'
8930 DATA ' aaaaaaaaaa',''
8940 :
8950 xout=RD_SPRT
8960 DATA 0,0,4
8970 DATA "aaaaaaaaaaaaaa"
8980 DATA "a a"
8990 DATA "a aa aa a"
9000 DATA "a aa aa aa a"
9010 DATA "a a a a"
9020 DATA "a a a a"
9030 DATA "a aa aa aa a"
9040 DATA "a aa aa a"
9050 DATA "a a"
9060 DATA "aaaaaaaaaaaaaa",""
9070 :
9080 InfoIt=RD_SPRT
9090 DATA 0,0,4
9100 DATA " aaaaaa "
9110 DATA " aawwaa "
9120 DATA " awwa "
9130 DATA " awwa "
9140 DATA " awwa "
9150 DATA " awwa "
9160 DATA " awwa "
9170 DATA " awwa "
9180 DATA " awwa "
9190 DATA " awwa "
9200 DATA " aawwaa "
9210 DATA " aaaaaa ",""
9220 :
9230 : REMark Some loose objects
9240 :
9250 m_nlit=2:DIM m_lflg%(m_nlit-1)
9260 main_lot=RD_LOTA(alt_iattr)
9270 DATA m_nlit
9280 DATA 16,lys,4+(lxs+4)*0,4,0,0,move$,sprite+retr,move_sprite
9290 DATA lxs-12,lys,MainXsize-28,4,0,0,cancel$,sprite+retr,xout
9300 :
9310 :
9320 : REMark The window definition itself
9330 :
9340 main_defn=RD_WDEF
9350 DATA 2,1,wndobrdr,wndopapr
9360 DATA MainXsize,MainYsize,0,0 : REMark maximum window size minus shadow
9370 DATA main_sprite,main_lot,main_iwt,main_awt
9380 :
9390 END DEFine Initialise
9400 :
9410 DEFine FuNction RD_SPRT
9420 LOCal tmp_patt$(64,64)
9430 LOCal xs,ys, xo,yo, md, l
9440 xs=0:ys=-1:READ xo,yo,md
9450 REPeat l
9460 READ x$:IF x$='' THEN EXIT l
9470 ys=ys+1:tmp_patt$(ys)=x$&FILL$(' ',32)
9480 IF LEN(x$)>xs THEN xs=LEN(x$)
9490 END REPeat l
9500 l=ALCHP(SPRSP(xs,ys+1))
9510 SPSET l,xo,yo,md,tmp_patt$(0 TO ys,1 TO xs)
9520 RETurn l
9530 END DEFine RD_SPRT
9540 :
9550 DEFine FuNction RD_WDEF
9560 LOCal lattr%(3)
9570 RD_WATT lattr%
9580 RETurn RD_WDEFA (lattr%)
9590 END DEFine RD_WDEF
9600 DEFine FuNction RD_WDEFA (lattr%)
9610 LOCal ldef%(3), lspr, lloose, linfo, lappl
9620 READ ldef%(0), ldef%(1), ldef%(2), ldef%(3)
9630 READ lspr, lloose, linf, lappl
9640 RETurn MK_WDEF (ldef%, lattr%, lspr, lloose, linf, lappl)
9650 END DEFine RD_WDEFA
9660 :
9670 DEFine FuNction RD_LOTA (lattr)
9680 LOCal nitem, cownt(3)
9690 READ nitem: IF nitem: nitem=nitem-1: RETurn RD_LOTN
9700 RETurn 0
9710 END DEFine RD_LOTA
9720 DEFine FuNction RD_LOTN
9730 LOCal item, ltyp, a$, lsk$
9740 LOCal ldef%(nitem,6), lptr(3,nitem), lstr$(nitem,85)
9750 lsk$=''
9760 FOR item = 0 TO nitem
9770 READ ldef%(item,0), ldef%(item,1), ldef%(item,2), ldef%(item,3)
9780 READ ldef%(item,4), ldef%(item,5)
9790 READ a$: lsk$=lsk$ & a$
9800 READ ltyp
9810 ldef%(item,6)=ltyp: ltyp=(ltyp MOD 256)/2
9820 IF ltyp
9830 READ lptr(ltyp,cownt(ltyp))
9840 ELSE
9850 READ lstr$(cownt(0))
9860 END IF
9870 cownt(ltyp)=cownt(ltyp)+1
9880 END FOR item
9890 RETurn MK_LIL (lattr, ldef%(TO, 0 TO 1), ldef%(TO, 2 TO 3), ldef%(TO, 4 TO 5), lsk$, ldef%(TO, 6), lstr$, lptr(1), lptr(2), lptr(3))
9900 END DEFine RD_LOTN
9910 :
9920 DEFine PROCedure RD_IATT (lattr)
9930 LOCal i
9940 READ lattr(0,0), lattr(0,1)
9950 FOR i=1 TO 3: READ lattr(i,0), lattr(i,1), lattr(i,2), lattr(i,3)
9960 END DEFine RD_IATT
9970 :
9980 DEFine PROCedure RD_WATT (lattr%)
9990 READ lattr%(0), lattr%(1), lattr%(2), lattr%(3)
10000 END DEFine RD_WATT