Nejprve však chci reagovat na některé komentáře.
- V tomto seriálu se chci zabývat tím, jak psát Screenlety a nechci je podrobně popisovat. Seriál je zaměřený na lidi, kteří vědí, co to je – většinou stejně člověk, co neví, co to je, je dělat nebude. Proto úvod do Screenletů je takový, jaký je.
- Neuvedl jsem v perexu, že to je pouze pro Gnome, protože pokud splňujete podmínku Compizu, tak to můžete mít i v KDE či jiném prostředí.
- Screenlety jsou psány v Pythonu, v ničem jiném.
- Někdo používá Conky, někdo zase Screenlety. Já se zde zabývám tím, jak takový Screenlet napsat.
__init__
se provádí úplně jako první (to je snad jasné),on_map
až, když se Screenlet kompletně načte. Například z příkladu můžete obsah metodyon_map
dát do__init__
v tomto případě. Chtěl jsem poukázat, že tu tato metoda také je – ne vždy se vše dá (musí) strčit do konstruktoru.
Začneme jednoduchou ukázkou
Pokud si dobře vzpomenete, tak jsme vlastně už minule nakreslili jeden objekt a napsali text. Text nám říkal, kolik je hodin a ten grafický objekt byl vlastně pozadí, který jsme vykreslili pomocí metody draw_rectangle
. Dnes se však budeme zabývat více kreslením.
V následující ukázce je změněna proměnná width
z 200 na 220 pixelů. Ostatní zůstává stejné z minulého příkladu.
def on_draw( self, ctx ): if self.scale > 5: self.scale = 5 ctx.save() ctx.scale( self.scale, self.scale ) ctx.set_source_rgba( 1, 1, 1, 0.1 ) self.draw_rounded_rectangle( ctx, 0, 0, 20, self.width, self.height, fill=False ) # ohraniceni self.draw_circle( ctx, 5, 5, self.height-10, self.height-10 ) # leve kolecko self.draw_circle( ctx, self.width-self.height+5, 5, self.height-10, self.height-10 ) # prave kolecko self.draw_triangle( ctx, self.width/2-10, self.height-12, 20, 10, fill=True ) # trojuhelnik dole uprostred foo = str( time.localtime()[3] ) + ':' + str( time.localtime()[4] ) + ':' + str( time.localtime()[5] ) ctx.set_source_rgba( 1, 1, 1 ) self.draw_text( ctx, 'Prave je '+foo, 45, 10, 'FreeSans', 12, self.width, 'center' ) ctx.restore()
V této ukázce jsou hned nové 4 metody, které zatím neznáme, ale z názvu je nejspíš jasné, co dělají – kreslí. Je tu i metoda, která se též stará o kreslení, ale pouze o barvu. To je důležité upozornění – musíme vědět, jakou barvu máme nastavenou, abychom se vyvarovali problému, že kreslíme text stejnou barvou (a průhledností) jako pozadí – to by bylo nepříjemné.
V proměnné ctx
je objekt cairo
, který nám vše kreslí. My používáme metody ze Screenletů a ty využívají právě knihovnu cairo
. O import se však starat nemusíme, pokud si nechceme vytvořit vlastní funkci, ve které tuto knihovnu budeme potřebovat.
set_source_rgba
Metoda, jak je určitě patrné, nastavuje barvu. Dnes si jen dodáme, jaké parametry obsahuje. První tři atributy jsou barvy po složkách RGB (Red, Green, Blue; Červená, Zelená, Modrá), přičemž rozmezí je od 0 do 1 a 1 je maximum (tedy 100%/255/FF). Poslední, čtvrtý, atribut je průhlednost, zde platí, že čím menší číslo, tím větší je průhlednost. Poslední atribut (tedy průhlednost) je nepovinný a defaultně je nastaven na hodnotu 1 (neprůhledný).
draw_rectangle
draw_rectangle( self, ctx, x, y, width, height, fill=True )
draw_rectangle
se v dnešní ukázce sice nevyskytuje, ale vyskytuje se v minulé. Jak již název metody napovídá, půjde o kreslení obdélníku (čtverce), přičemž souřadnice nastavíme atributy x
a y
a velikost pomocí atributů width
a height
. Poslední atribut fill
(který je defaultně True
) nastavuje, zda obdélník vyplnit nebo nakreslit pouze rámeček. Nesmíme však zapomenout na první atribut ctx
, kterým předáváme naši proměnnou ctx
(tedy náš objekt cairo
).
draw_rounded_rectangle
draw_rounded_rectangle( self, ctx, x, y, rounded_angle, width, height, round_top_left=True, round_top_right=True, round_bottom_left=True, round_bottom_right=True, fill=True )
Tato metoda nám může nakreslit nějaký obdélník (čtverec) jako předešlá metoda, ale s oblými rohy. Vše je stejné, až na to, že mezi atributy souřadnice a rozměry přibyl atribut rounded_angle
, který udává míru zaoblení. Dále přibyly atributy round_top_left
, round_top_right
, round_bottom_left
a round_bottom_right
, pomocí kterých můžete změnit zaoblení jednotlivých rohů.
draw_circle
draw_circle( self, ctx, x, y, width, height, fill=True )
Další metodu, kterou jsem v ukázce použil, je draw_circle
, která se nám stará o kreslení kruhů. Tato metoda má stejné parametry jako draw_rectangle
pro kreslení obdélníků, jen upozorním, že atributy pro souřadnice určují také levý horní roh, nikoliv střed kruhu.
draw_triangle
draw_triangle( self, ctx, x, y, width, height, fill=True )
Metodu draw_triangle
nebudu extra popisovat, je stejná jako v případě draw_rectangle
či draw_circle
, jediný rozdíl je, že touto metodou budeme kreslit trojúhelníky.
draw_text
draw_text( self, ctx, text, x, y, font, size, width, allignment, weight=0, ellipsize=<enum PANGO_ELLIPSIZE_NONE of type PangoEllipsizeMode> )
A konečně poslední, asi nejčastěji používaná metoda draw_text
. S ní vypisujeme text a jako první atribut je ctx
, poté následuje text, který chceme vypsat, dále souřadnice (levého horního rohu) a nakonec atributy spojené s textem (snad netřeba rozebírat): font
, size
, width
a allignment
.
Poslední atribut je ellipsize
, kterým určujeme, co se má stát, pokud je text dlouhý. Defaultně se nestane „nic“ a text se natáhne na další řádek, pokud tuto vlastnost nechceme, můžeme přidat tři tečky (…) na začátek, konec nebo střed řetězce. Volby, které můžete vložit, a co přesně dělají, naleznete například zde. Jen musíte pro tuto volbu importovat modul pango
. Ještě ukážu ukázku vložení tří teček uprostřed řetězce, pokud je řetězec dlouhý:
self.draw_text( ctx, 'toto je velmi dlouhy retezec, ktery se do jednoho radku (220px) nevejde', 0, 10, 'FreeSans', 12, 220, 'center', ellipsize=pango.ELLIPSIZE_MIDDLE )
Výsledek
A výsledek dnešního snažení bude vypadat jako na následujícím obrázku.
![Screenlety 2](https://i.iinfo.cz/images/42/screenlety-2.png)
Další grafické metody
Nakonec uvedu další metody, které můžete při vykreslení Screenletu použít. Jako za domácí úkol si některé vyzkoušejte.
Pro kreslení čar využijeme draw_line
.
draw_line( self, ctx, start_x, start_y, end_x, end_y, line_width=1, close=False, preserve=False )
Občas se hodí nakreslit i nějaký obrázek. To provedeme metodou draw_image
pro kreslení obrázku v původní velikosti nebo draw_scaled_image
, pokud chceme obrázku změnit velikost. Jako atribut pix
napíšeme úplnou cestu k obrázku. Pokud chceme vykreslit ikonu, tak tu je na to speciální funkce draw_icon
. Jediná změna u draw_icon
je ta, že v atributu pix
neuvádíme úplnou cestu k ikoně, ale pouze její název.
draw_image( self, ctx, x, y, pix ) draw_scaled_image( self, ctx, x, y, pix, w, h ) draw_icon( self, ctx, x, y, pix, width=32, height=32 )
Dále tu je metoda draw_rectangle_advanced
, pomocí které nějaký ten obdélník nadefinujeme opravdu podrobně. Máme tu možnost definovat pozici, velikost i zda vyplnit či kreslit jen rámeček a navíc tu je možnost pomocí N-tice (tuple) nastavit jednotlivé zaoblení rohů (postupně levý horní, pravý horní, levý dolní a pravý dolní), nastavení rámečku (velikost či barvu pomocí N-tice opět jako RGB + průhlednost v rozmezí od nuly do jedničky) nebo také přidat stín (stejné možnosti jako v případě rámečku).
draw_rectangle_advanced( self, ctx, x, y, width, height, rounded_angles=( 0, 0, 0, 0 ), fill=True, border_size=0, border_color=( 0, 0, 0, 1 ), shadow_size=0, shadow_color=( 0, 0, 0, 0.5 ) )
V předchozí metodě jsme mohli udělat i stín, ten jde však udělat i samostatně, pomocí následujících metod. draw_shadow
udělá klasický stín dokola souřadnic. draw_side_shadow
udělá přechod – z průhledný do určené barvy (atributem col
), atribut side
určuje z jaké strany je úplně průhledná (0 vlevo, 1 vpravo, 2 nahoře, 3 dole). Poslední draw_quadrant_shadow
tu nebudu detailně popisovat, podívejte se na její zdrojový kód v dokumentaci a jen prozradím, že se to dá použít v rozích jako rohové (kulaté / zaoblené) stíny.
draw_shadow(self, ctx, x, y, w, h, shadow_size, col)
draw_side_shadow(self, ctx, x, y, w, h, side, col)
draw_quadrant_shadow( self, ctx, x, y, from_r, to_r, quad, col)
Příště
Opět trošku experimentujte a příště se u kreslení ještě pozastavíme a naučíme se kreslit pomocí bufferů.