Squeak je primárně určen pro provoz s grafickým rozhraním. Kvůli obecnosti a přenositelnosti naprosto pomíjí prostředky hostitelského systému a GUI si vytváří celé sám vlastními prostředky. Od VM vyžaduje pouze schopnost zobrazovat bitové mapy daných rozměrů a barevné hloubky na obrazovku.
Grafické možnosti jednotlivých platforem se často velmi výrazně liší. Celé prostředí musí být schopno pracovat jak na kapesních počítačích s malými obrazovkami, tak na stolních počítačích, kde se může opřít o akcelerovanou grafiku za vydatné pomoci OpenGL či DirectX. Protože Squeak od hostitelského systému vyžaduje velmi málo, dokáže se obejít i bez XServeru a jeho virtuální stroj si vystačí s pouhým framebufferem. Existují dokonce poměrně pokročilé projekty implementující XServer přímo ve Squeaku, takže se časem nepochybně dočkáme toho, že si Squeak a hostitelský OS v oblasti zpřístupnění grafického rozhraní vymění role.
Squeak se lehce vypořádává i s velmi nízkým rozlišením a je bez problémů použitelný i při volbě jednobitové barevné hloubky. Přechod na jiné parametry displaye se image prakticky nedotkne, a lze tudíž plynule přecházet s jedinou verzí image např. mezi kapesním počítačem a pracovní stanicí. Stačí ji jen spustit pod jinou verzí VM a můžete dál nerušeně pracovat.
Grafické uživatelské rozhraní Squeaku je bezesporu jednou z jeho nejkontroverznějších částí. Na jednu stranu by se na něj dala pět chvála od rána až do noci, nicméně stejně tak bych jej mohl bez výčitek okamžitě zavrhnout. Pravda je, jako obvykle, někde uprostřed.
MVC
Aby to nebylo tak jednoduché, nemá Squeak grafické uživatelské rozhraní jedno, ale hned dvě. Prvním je stařičké MVC (Model-View-Controller). Jedná se původní smalltalkovské GUI, které se stalo vzorem celé řady svých následníků a v něm použité návrhové vzory se nezřídka používají dodnes. Z dnešního pohledu vypadá již značně omšele, nicméně stále má uživatelům co nabídnout. Na první pohled zaujme jeho extrémní úspornost. Nenajdete v něm skoro nic jiného než obdélníková jednoduchá okna s titulkem a ikonkami pro zavření a minimalizaci. Dokonce nemá ani typické scrollbary, ty se vysouvají až v případě, že myš přesunete nad okno, s nímž chcete pracovat. Ty dnešní připomínají jen vzdáleně, nicméně umí toho daleko více. Jsou horizontálně rozděleny na čtyři zóny. Jedna se chová stejně jako dnešní scrollbary, dvě slouží pro scrollování po stránkách nahoru a dolů, třetí nahrazuje kliknutí tzv. žlutým tlačítkem myši otvírajícím kontextová menu.
Ovládání Smalltalku je od jeho zrodu založeno na využívání třítlačítkové myši. Každé tlačítko je pojmenováno po nějaké barvě – červené, modré nebo žluté. Hlavní levé tlačítko používané pro práci s objekty má červenou barvu. Mapování dalších dvou tlačítek je obecně různé. Pokud vám standardní nastavení pro vaši platformu nevyhovuje, k úpravě tohoto mapování slouží se Squeaku volba swapMouseButtons v Preferences. Žluté tlačítko se používá především pro vyvolání kontextových menu, modré tlačítko pro správu oken.
Pokud hovoříme o mapování tlačítek myši, nelze se nezmínit o mapování funkčních kláves. Squeak používá mapování, které má oproti současnému mainstreamu prohozené klávesy Alt a Ctrl. Ke kopírování do schránky tak např. slouží klávesová zkratka Alt+c. Rovněž toto nastavení lze změnit v Preferences, konkrétně volbou swapControlAndAltKeys. K nástroji Preferences se dostanete buď přes záložku Tools, či kliknutím levým tlačítkem na plochu – appearance – preferences.
MVC framework slouží jako modelový příklad využití návrhového vzoru observer (pozorovatel). Odděluje model spravující data a logiku, pohled zajišťující vhodné zprostředkování dat a controller, který se stará o ovládání a komunikaci s okolím.
MVC se dodnes v praxi používá v minimalizovaných image a je ideální volbou, pokud máme k dispozici pouze malý display, nijak oslňující výpočetní výkon nebo jednobitovou barevnou hloubku.
Morphic
Morphic je současné preferované GUI Squeaku. Smalltalk udával směr vývoje grafických uživatelských rozhraní a Morphic se na tuto tradici snaží navázat. Můžete si o Morphicu myslet cokoliv, ale jedno mu nelze upřít. Možnosti, které uživatelům nabízí, jsou naprosto brutální a jen stěží nachází srovnání s čímkoliv, co je v současné době k dispozici. Mimo jiné se jedná o možnost jakýkoliv grafický prvek natočit pod libovolným úhlem a pracovat s ním beze změny dál, což se týká například i přehrávačů filmů.
Morphic je založen na velmi jednoduchých a obecných základech. Abychom si je přiblížili, trochu si s ním pohrajeme.
Otevřete si Workspace (menu plochy – open – workspace), napište a vyhodnoťte (do it) výraz
m := Morph new openInWorld.
V levém horním rohu obrazovky se nám objevil malý modrý obdélníček, který si myší můžeme kamkoliv přesunout. Je to tzv. morph, základní objekt Morphicu. Podobně jako ve Smalltalku je všechno objekt, v Morphicu je všechno morph. Konstruktor new nám vytvořil objekt morphu, metoda openInWorld jej pak zobrazila. Všimněte si, že jsme nikde nedeklarovali proměnnou m. Okno Worspace nás této povinnosti zbavuje. Pokračujme dále.
m layoutPolicy: TableLayout new. m hResizing: #shrinkWrap. m vResizing: #shrinkWrap.
Nyní jsme pro náš morph nadefinovali způsob rozložení pro jeho podmorphy – konkrétně, aby použil tabulkové rozložení. Následně jsme mu pomocí zpráv hResizing: a vResizing: řekli, aby upravoval svoji velikost podle svých podmorphů. Všimněte si použití symbolů. Symboly se ve Smalltalku velmi často používají tam, kde se v řadě jiných jazyků vyskytují výčtové typy.
World submorphs do: [:morph | (morph isSystemWindow and: [morph isCollapsed]) ifTrue: [m addMorph: morph] ].
Globální objekt World je hlavní morph reprezentující pracovní plochu. Pro všechny jeho podmorphy jsme zjistili, zda se jedná o systémová okna a zda jsou minimalizovaná. Pokud ano, pak jsme je přidali do našeho morphu. Tím jsme z něj vytvořili kontejner na tato minimalizovaná okna. Pokud některé z nich opět maximalizujeme, zůstane stále jako podmorph našeho morphu.
Samozřejmě většinou budeme chtít vytvářet vlastní třídy morphů. Taková třída může vypadat třeba takto:
Morph subclass: #MujMorph instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'MojeMorphy'
Jednou z nejdůležitějších metod, kterou bychom morphu měli přetížit, je zpráva drawOn:
drawOn: aCanvas
aCanvas fillOval: (self bounds) color: (Color red alpha: 0.5).
Zajišťuje vykreslování objektu a standardně vykresluje právě onen modrý obdélník. Parametr aCanvas je třídy FormCanvas a implementuje základní kreslící operace. Mezi nimi i metodu fillOval:color:, která vykreslí ovál určité barvy do daného obdélníku. Metoda bounds třídy Morph vrátí jeho hranice, barvu jsme zvolili červenou a specifikovali jsme u ní poloviční průhlednost. Získali jsme tedy průhledný červený oválový morph.
Pokud jej chceme naučit reagovat na nějaké zprávy, např. stisk myši, implementujeme u něj tyto metody:
handlesMouseDown: evt ^ true. mouseDown: evt self beep.
Tím jsme našemu morphu řekli, že má reagovat na stisk myši a při každém stisku pípnout. Nicméně takto přijdeme o možnost ho pomocí myši přesouvat. Proto upravíme metodu handlesMouseDown: následovně
handlesMouseDown: evt ^ evt shiftPressed not.
Díky tomu se metoda mouseDown: bude volat jen v případě, že není stisknuta klávesa Shift.
Ještě by se hodila nějaká animace. Nejdříve mu v metodě stepTime nadefinujeme frekvenci časovače (v milisekundách).
stepTime ^ 10
Pak morphu řekneme, aby se při jeho inicializaci tento časovač zapnul:
initialize super initialize. self startStepping.
Nesmíme zapomenout zavolat inicializaci předka. Na závěr nadefinujeme, co se má vlastně provést. My budeme při každém tiku časovače posouvat náš morph o jeden pixel na ose x. Binární zpráva @ se používá pro konstrukci instancí třídy Point.
step self position: (self position + (1@0)).
Instanci našeho morphu vytvoříme výrazem MujMorph new openInWorld. Pokud máme již vytvořený živý morph (týká se to všech objektů obecně) a měníme definici jeho třídy, bez problémů to přežije a bude se chovat podle nově definovaných vlastností.
Jak vidíte, je programování v Morphicu velice jednoduché a intuitivní. Pracuje tak, že neustále v jedné smyčce provádí následující úkoly:
- zpracuje vstupy
- pošle zprávu step všem aktivním morphům
- přepočítá rozložení morphů
- překreslí obrazovku
Na rozdíl od MVC slučuje Morphic roli pohledu a controlleru a výrazně se liší například v přístupu k časovačům. Nicméně pomocí speciálních tříd lze psát aplikace, které pracují stejně jak v MVC, tak v Morphicu. Tyto třídy pro tlačítka, listboxy apod. mají prefix Pluggable a je pomocí nich vytvořeno např. rozhraní základních vývojových nástrojů (Browser, Workspace apod.).
Morphic není původním výplodem chorých myslí squeakerů, ale jedná se o port prostředí použitého v programovacím jazyce Self společnosti Sun Microsystems. Jazyk Self je beztřídní varianta Smalltalku – jde tedy v koncepci objektové orientace ještě o kousek dál než Smalltalk. Pokud se vám zdá samotný Smalltalk málo čistý a příliš nudný, pak je Self pro vás jako dělaný.
K manipulaci s morphy slouží tzv. halos. Vyvolávají se kliknutím modrým tlačítkem myši na morph. Další kliknutí pak přijímají jeho podmorphy, díky čemuž se lze proklikat celou hierarchií podmorphů. Halos jsou malé ikonky, které se objeví v okolí označeného morphu. Umožňují zavřít morph, vyvolat jeho kontextové menu, odpoutat ho z rodičovského morphu, přesouvat ho, vytvářet jeho kopii, minimalizovat ho, ladit ho, generovat jeho textovou reprezentaci, měnit jeho barvu, rotovat s ním a měnit jeho velikost. V kontextovém menu morphu je pak přístupné nepřeberné množství operací, které s libovolným morphem lze dělat. Od změny vlastností rozložení submorphů, exportu do různých grafických formátů přes vkládání do jiných morphů až po vrhání stínu. Kontextová menu i halos lze přirozeně libovolně upravovat.
Pokud si budete chtít v Morphicu doslova naklikat nějakou aplikaci, jde to a celkem pohodlně, ale prostředky, které k tomu dostanete, se od běžně používaných vývojových nástrojů velmi silně liší. Důvod je prostý. Smalltalk v podstatě vznikl omylem. Jedním z hlavních cílů jeho autorů bylo, aby v něm mohly pracovat i děti. Nicméně když dospěl do konečné fáze, bylo jasné, že se sice jedná o vynikající revoluční výtvor, ale přes svoji jednoduchost je pro děti nepoužitelný.
Morphic ve Squeaku si dal za cíl zpřístupnit programování právě malým dětem a celý je tomuto cíli přizpůsoben. Ne náhodou krom společnosti Apple stojí u počátků Squeaku i Walt Disney Company.
Typické programování v Morphicu vypadá tak, že si nakreslíte autíčko, volant a během chvilky autíčko rozjedete. Za mocného otáčení volantu pomocí halos se pak se svým bourákem neohroženě řítíte po pracovní ploše. Tam, kde v jiných vývojových nástrojích najdete tlačítka, combo-boxy, databázové tabulky, kalendáře apod., máte ve Squeaku elipsy, hvězdičky a joysticky.
Typické programování v Morphicu neprobíhá v Browseru. Svoji aplikaci sestavujete z již předem připravených morphů, které si podle libosti skládáte na pracovní plochu a pomocí tzv. Vieweru nastavujete jejich parametry, píšete nebo pouhým přetahováním standardních programových bloků vytváříte skripty a reakce na jednotlivé události. Pro vaše morphy se automaticky vytvářejí třídy (dědí od třídy Player), kam se váš kód zapisuje. Svoji aplikaci s minimální námahou sestavujete zaživa, abyste ji nakonec vyexportovali jako projekt a vystavili třeba na Internet.
Do problémů se dostanete, pokud budete chtít vytvořit něco, co vypadá jako konvenční aplikace. Morphic spíše než k prototypování a vytváření aplikací slouží pro prototypování grafických uživatelských rozhraní jako takových. Není problém si v něm udělat poměrně snadno třeba vlastní combo-box, ale už udělaný ho ve standardním Squeaku nikde nenajdete.
Když uvidíte poprvé Squeak, vás zcela jistě jako první věc nenapadne, že se díváte na v mnoha ohledech nejmodernější a nejdynamičtěji se rozvíjející implementaci Smalltalku. Že to, co dostáváte do ruky, není hračka s nijak oslnivým vzhledem, ale jedno z nejvýkonnějších vývojových prostředí současnosti.
Je to škoda, protože GUI Squeaku velmi rychle odradí velkou část zájemců, kteří tak ani nemají dostatek času, aby jeho schopnosti plně docenili. Squeakerská komunita si to samozřejmě uvědomuje a existuje několik projektů, které se snaží tuto problematiku nějak řešit. Mezi nejzajímavější patří Zurgle, které nejenže dokáže Squeaku dodat XPéčkovský design, ale rovněž obsahuje morphy pro základní prvky uživatelského rozhraní, jako jsou již zmíněné combo-boxy, záložky apod. Vše je stále postaveno na Morphicu, takže i XP-like okno si můžete klidně postavit vzhůru nohama a dál s ním pracovat. Na těchto prostředcích je stále co dohánět, nicméně pravdou je, že principiálně není problém nad Morphicem vytvořit relativně jednoduše GUI builder, který by sám generoval příslušné třídy a umožňoval takovou flexibilitu, o které se dnešním vývojovým nástrojům ani nezdá. Něco takového je ovšem stále hudba budoucnosti.
Dnes Microsoft předvádí ohromeným davům ve vývojových verzích Longhornu rotující tlačítka. Squeak umí už mnoho let mnohem více. Je dokonce možné ovládat jedno prostředí pomocí hned několika uživatelů, z nichž každý má vlastní kurzor myši. Možnosti Morphicu mnohdy berou dech, na druhou stranu si jeho uživatelé musí zvyknout na několik odlišností od dnešních standardních GUI. Například focus okna je určen pozicí kurzoru myši. Bez myši si v Morphicu prakticky ani neškrtnete. Vzhled je sice nezvyklý, ale s každou další verzí vypadá lépe a je snadno obměnitelný. Největší zrada na uživatele Morphicu se však skrývá v jeho útrobách.
O hlavním cyklu Morphicu jsme se zmínili. V běžných grafických rozhraních má každá aplikace vlastní cyklus, ve kterém zpracovává obdržené zprávy. Morphic se drží toho, že Squeak je celá vaše aplikace, to znamená, že Morphic má jen jeden cyklus zpráv. To nelze označit jinak než jako obrovskou koncepční vadu. V praxi to znamená, že pokud například ve Workspace dáte vypočítat factorial nějakého velkého čísla či z vašeho programu spustíte časově náročný výpočet, všechna vlákna v systému pracují tak, jak mají, ale GUI totálně zamrzne. Pokud nechcete čekat do konce vykonávání výpočtu, pomůže jen jeho přerušení pomocí kombinace kláves Alt+tečka.
Ve vašich aplikacích vám pak nezbude nic jiného než pouštět náročné výpočty v separátních vláknech nebo průběžně explicitně volat cyklus Morphicu pomocí příkazu World doOneCycle.
Toto není vada Squeaku jako takového, takže pokud vám z nějakého důvodu nevyhovuje MVC ani Morphic, máte ještě jednu možnost. Vytvořit si grafické prostředí celé sami. Stačí obsadit senzor přijímající vstupy od uživatele a můžete si udělat vlastního správce oken založeného na naprosto jiných principech. Viděl jsem v činnosti funkční základ experimentálního grafického prostředí pro Squeak, které oddělovalo vlákna jednotlivých aplikací. Zasílání zpráv se provádělo prostřednictvím sdílených rour, takže se po stránce vláknové bezpečnosti chovalo mnohem lépe než MVC nebo Morphic.
Když pomineme využívání rozhraní pro různé grafické toolkity hostitelských systémů, které jsou však stále ve vývojových fázích, máte ještě jednu možnost – nepoužít grafické prostředí vůbec. Squeak dokáže běžet na pozadí (headless), přičemž komunikovat se svým okolím může třeba jako webový server.