Visual Python


Interakcija z miško

Uvod

Za sceno imamo še atribut "mouse". Če tako želimo uporabiti vhod miške, naslovimo "scene.mouse". Oglej si osnovne primere s klikom oziroma vlečenjem miške.

Objekt "mouse" ima vrsto atributov, ki ustrezajo trenutnemu stanju miške. Ima tudi metodi  getevent() in getclick(), ki vrneta objekt s podobnimi atributi, ki ustrezajo stanju miške, ko smo na njej zadnjič uporabili gumbe. Če gumbov  še nismo uporabili, obe metodi -  getevent() oziroma getclick() - ustavita izvajanje programa, dokler kaj takega ne storimo.


Trenutno stanje miške

pos: Trenutni 3D položaj kurzorja miške  "scene.mouse.pos". . Vpython vedno izbere točko na ravnini, ki je vzporedna z zaslonom in poteka skozi "display.center". (Druge možnosti so podane pod  Projekcija kurzorja miške na dano ravnino.)

button = None (nismo kliknili na noben mišji gumb), oziroma  'left', 'right', 'middle' ali 'wheel' (kliknili smo s koleščkom na miški). Primer: 

  if  (scene.mouse.button == 'left') # je true, ce sje levi gumb trenutno dol

pick:  Tako izberemo iz scene objekt, ki je najbližje oziroma pod kurzorjem (velja le za krogle, kvadre, cilindre in konveksna telesa). Izbrani objekt je "scene.mouse.pick". Če nismo izbrali nobenega objekta, je vrednost tega atributa "None".

pickpos 3D točka na površini izbranega objekta, ki pade pod kurzor. Če objekta nismo izbrali, je ta atribut enak "None". Primer klica tega atributa:

tocka = scene.mouse.pickpos

camera"scene.mouse.camera" je položaj kamere, ki nanj vpliva uporabnik, ne pa program. Tako je na primer  "mag(scene.mouse.camera-scene.center)" razdalja od središča scene do trenutne lokacije kamere. Sam položaj in usmeritev kamere lahko določimo z atributoma  "scene.forward" in "scene.center" opisanema v poglavju o krmiljenju oken.

ray: enotni vektor, usmerjen od kamere v smeri kurzorja miške. točke pod kurzorjem miške so { camera + t*ray  za  t>0}. Atributa "camera" in "ray" definirata vse 3D točke pod mišjim kurzorjem.


project():  Projicira pozicijo na ravnino,  Glej  Projekcijo kurzorja miške na dano ravnino.

alt = 1 če je pritisnjena tipka  ALT, sicer je ta atribut enak 0

ctrl = 1 če je pritisnjena tipka CTRL, sicer je ta atribut enak 0

shift = 1 če je pritisnjena tipka SHIFT, sicer je ta atribut enak 0

Dogodki

Imamo 4 vrste dogodkov z miško: press, click, drag in drop:

   Dogodek "press" nastopi, ko pritisnemo  nek mišji gumb.

   Dogodek "click" nastopi, ko so vsi mišji gumbi sproščeni in pri tem ni prišlo do premikanja miške. Glej primer  s klikom

   Dogodek "drag" nastopi, ko po pritisku na mišji gumb z miško povlečemo tako, da gumb še vedno tiščimo. Tako lahko premikamo objekte. Glej primer z vlečenjem

   Dogodek "drop" nastopi po dogodku "drag", ko spustimo mišje gumbe.  

Med dogodkoma "drag" (začetek vlečenja) in "drop" (konec vlečenja) ni drugih dogodkov. Lahko pa preverjamo položaj miške s "scene.mouse.pos". 

Sicer pa lahko dobimo podatke o dogodkih (ki se uvrščajo v vrsto) na naslednji način:

events Število uvrščenih dogodkov (press, click, drag, drop). Na primer:

 steviloDogodkov = scene.mouse.events

Vse dogodke lahko "pozabimo", če napišemo

scene.mouse.events = 0

Drugih vrednosti, različnih od 0 ne smemo vpisati.

getevent():  Vrne najbolj zgodnji dogodek z miško in ga umakne iz vhodne vrste dogodkov. Če še ni bilo nobenega mišjega dogodka (kar pomeni, da je "scene.mouse.events" enak nič), čaka metoda "getevent()"  na kakšen mišji dogodek in tako začasno zaustavi program. "getevent()" vrne objekt z atributi , enakimi objektu "mouse" (torej:  pos, button, pick, pickpos, camera, ray, project(), alt, ctrl, and shift). Vrednosti teh atributov ustrezajo stanju, ko je prišlo do dogodka.

Če nas zanima katerikoli mišji dogodek, uporabimo  "events" oziroma "getevent()". Če pa nas morda zanima le klikanje z levim mišjim gumbom, uporabljamo "clicked" in "getclick()".

clicked Število levih klikov z miško (torej uporabimo "scene.mouse.clicked"). To ne upošteva drugih mišjih dogodkov (press, drag, drop).

getclick():  Vrne najbolj zgoden levi mišji klik (pritisk in sprostitev levega mišjega gumba)  in ta dogodek umakne iz vrste pomnjenih dogodkov. Pri tem izloči tudi vse predhodne dogodke tipa press, drag ali drop. Če do klika še ni prišlo, čaka ta metoda na prvi klik in tako začasno zaustavi program.

Ta metoda je uporabna na primer za "razhroščevanje" programa, saj lahko na danem mestu programa tega zaustavimo in si sceno v miru ogledamo. Po kliku pa se program nadaljuje.

Dodatni podatki, ki jih vrneta getevent() oziroma getclick()

press = 'left' ali 'right' ali 'middle' v primeru dogodka "press", sicer je ta atribut enak "None"

click = 'left' ali 'right' ali 'middle' v primeru dogodka "click", sicer "None". V tem primeru atributi "pos" in drugi ustrezajo stanju miške ob nastopu dogodka. Poglej primer s klikom miške.

drag = 'left' ali 'right' ali 'middle' v primeru dogodka "drag", sicer je ta atribut enak "None". V tem primeru atributi "pos" in drugi ustrezajo stanju miške ob nastopu dogodka. Poglej primer z vlečenjem  miške.

drop = 'left' ali 'right' ali 'middle' v primeru dogodka "drop", sicer je enak "None"

release = 'left' ali 'right' ali 'middle' , ko dogodku "click" sledi dogodek "drop", sicer je ta atribut enak "None".

Običajno vlečenje z desnim oziroma srednjim mišjim gumbom pomeni v Vpythonu vrtenje oziroma povečavo prikaza scene. Lahko pa uporabnikovo vrtenje oziroma povečavo scene izklopimo ( scene.userspin = 0 oziroma  scene.userzoom = 0).

Projekcija kurzorja miške na dano ravnino

Tako projiciramo kurzor miške na ravnino, ki je pravokotna na podano normalo. Če točka ni določena, gre ravnina skozi izhodišče. Metoda vrne 3D pozicijo ali pa "None", če projekcija miške ne pade v ravnino. Tako dobimo položaj miške relativno na določeno ravnino v prostoru:

tocka = scene.mouse.project(normal=(0,1,0), point=(0,3,0))
if tocka: # tocka je None, ce ni preseka z ravnino
    krogla.pos = tocka

V zgornjem primeru bo uporabnik lahko postavil kroglo na ravnino, vzporedno ravnini xy in na višini 3 nad to ravnino, ne glede na to, kako je naše gledišče zavrteno.

Drug način je, da podamo razdaljo d med izhodiščem in ravnino, ki je pravokotna na podano normalo. Zgornji primer je tako ekvivalenten naslednjemu:  

tocka = scene.mouse.project(normal=(0,1,0), d=3)