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.
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ů.