tools.py 229 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879
  1. """
  2. @package nviz.tools
  3. @brief Nviz (3D view) tools window
  4. Classes:
  5. - tools::NvizToolWindow
  6. - tools::PositionWindow
  7. - tools::ViewPositionWindow
  8. - tools::LightPositionWindow
  9. (C) 2008-2011 by the GRASS Development Team
  10. This program is free software under the GNU General Public License
  11. (>=v2). Read the file COPYING that comes with GRASS for details.
  12. @author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
  13. @author Enhancements by Michael Barton <michael.barton asu.edu>
  14. @author Anna Kratochvilova <kratochanna gmail.com> (Google SoC 2011)
  15. """
  16. import os
  17. import sys
  18. import copy
  19. import types
  20. import wx
  21. import wx.lib.colourselect as csel
  22. import wx.lib.scrolledpanel as SP
  23. import wx.lib.filebrowsebutton as filebrowse
  24. try:
  25. import wx.lib.agw.flatnotebook as FN
  26. except ImportError:
  27. import wx.lib.flatnotebook as FN
  28. try:
  29. from agw import foldpanelbar as fpb
  30. except ImportError: # if it's not there locally, try the wxPython lib.
  31. try:
  32. import wx.lib.agw.foldpanelbar as fpb
  33. except ImportError:
  34. import wx.lib.foldpanelbar as fpb # versions <=2.5.5.1
  35. try:
  36. import wx.lib.agw.floatspin as fs
  37. except ImportError:
  38. fs = None
  39. import grass.script as grass
  40. from core import globalvar
  41. from core.utils import _
  42. from gui_core.gselect import VectorDBInfo
  43. from core.gcmd import GMessage, RunCommand
  44. from modules.colorrules import ThematicVectorTable
  45. from core.settings import UserSettings
  46. from gui_core.widgets import ScrolledPanel, NumTextCtrl, FloatSlider, SymbolButton
  47. from gui_core.gselect import Select
  48. from core.debug import Debug
  49. try:
  50. from nviz.mapwindow import wxUpdateProperties, wxUpdateView,\
  51. wxUpdateLight, wxUpdateCPlane
  52. import wxnviz
  53. except ImportError:
  54. pass
  55. class NvizToolWindow(FN.FlatNotebook):
  56. """Nviz (3D view) tools panel
  57. """
  58. def __init__(self, parent, tree, display, id=wx.ID_ANY,
  59. style=globalvar.FNPageStyle | FN.FNB_NO_X_BUTTON,
  60. **kwargs):
  61. Debug.msg(5, "NvizToolWindow.__init__()")
  62. self.parent = parent
  63. self.tree = tree
  64. self.mapDisplay = display
  65. self.mapWindow = display.GetWindow()
  66. self._display = self.mapWindow.GetDisplay()
  67. if globalvar.hasAgw:
  68. kwargs['agwStyle'] = style
  69. else:
  70. kwargs['style'] = style
  71. FN.FlatNotebook.__init__(self, parent, id, **kwargs)
  72. self.SetTabAreaColour(globalvar.FNPageColor)
  73. self.win = {} # window ids
  74. self.page = {} # page ids
  75. # view page
  76. self.AddPage(page=self._createViewPage(),
  77. text=" %s " % _("View"))
  78. # data page
  79. self.AddPage(page=self._createDataPage(),
  80. text=" %s " % _("Data"))
  81. # appearance page
  82. self.AddPage(page=self._createAppearancePage(),
  83. text=" %s " % _("Appearance"))
  84. # analysis page
  85. self.AddPage(page=self._createAnalysisPage(),
  86. text=" %s " % _("Analysis"))
  87. # view page
  88. self.AddPage(page=self._createAnimationPage(),
  89. text=" %s " % _("Animation"))
  90. self.UpdateSettings()
  91. self.mapWindow.SetToolWin(self)
  92. self.pageChanging = False
  93. self.vetoGSelectEvt = False # when setting map, event is invoked
  94. self.mapWindow.render['quick'] = False
  95. self.mapWindow.Refresh(False)
  96. # bindings
  97. self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
  98. self.Bind(wx.EVT_SIZE, self.OnSize)
  99. self.mapWindow.GetAnimation().animationFinished.connect(self.OnAnimationFinished)
  100. self.mapWindow.GetAnimation().animationUpdateIndex.connect(
  101. self.OnAnimationUpdateIndex)
  102. Debug.msg(3, "NvizToolWindow.__init__()")
  103. self.Update()
  104. wx.CallAfter(self.SetPage, 'view')
  105. wx.CallAfter(
  106. self.UpdateScrolling,
  107. (self.foldpanelData,
  108. self.foldpanelAppear,
  109. self.foldpanelAnalysis))
  110. wx.CallAfter(self.SetInitialMaps)
  111. def SetInitialMaps(self):
  112. """Set initial raster and vector map"""
  113. for ltype in ('raster', 'vector', 'raster_3d'):
  114. selectedLayer = self.tree.GetSelectedLayer(
  115. multi=False, checkedOnly=True)
  116. if selectedLayer is None:
  117. continue
  118. selectedLayer = self.tree.GetLayerInfo(
  119. selectedLayer, key='maplayer')
  120. layers = self.mapWindow.Map.GetListOfLayers(
  121. ltype=ltype, active=True)
  122. if selectedLayer in layers:
  123. selection = selectedLayer.GetName()
  124. else:
  125. try:
  126. selection = layers[0].GetName()
  127. except:
  128. continue
  129. if ltype == 'raster':
  130. self.FindWindowById(
  131. self.win['surface']['map']).SetValue(selection)
  132. self.FindWindowById(
  133. self.win['fringe']['map']).SetValue(selection)
  134. elif ltype == 'vector':
  135. self.FindWindowById(
  136. self.win['vector']['map']).SetValue(selection)
  137. elif ltype == 'raster_3d':
  138. self.FindWindowById(
  139. self.win['volume']['map']).SetValue(selection)
  140. def UpdateState(self, **kwargs):
  141. if 'view' in kwargs:
  142. self.mapWindow.view = kwargs['view']
  143. self.FindWindowById(
  144. self.win['view']['position']).data = kwargs['view']
  145. self.FindWindowById(self.win['view']['position']).PostDraw()
  146. if 'iview' in kwargs:
  147. self.mapWindow.iview = kwargs['iview']
  148. if 'light' in kwargs:
  149. self.mapWindow.light = kwargs['light']
  150. self.FindWindowById(
  151. self.win['light']['position']).data = kwargs['light']
  152. self.FindWindowById(self.win['light']['position']).PostDraw()
  153. if 'fly' in kwargs:
  154. self.mapWindow.fly['exag'] = kwargs['fly']['exag']
  155. def LoadSettings(self):
  156. """Load Nviz settings and apply to current session"""
  157. view = copy.deepcopy(
  158. UserSettings.Get(
  159. group='nviz',
  160. key='view')) # copy
  161. light = copy.deepcopy(
  162. UserSettings.Get(
  163. group='nviz',
  164. key='light')) # copy
  165. fly = copy.deepcopy(UserSettings.Get(group='nviz', key='fly')) # copy
  166. self.UpdateState(view=view, light=light, fly=fly)
  167. self.PostViewEvent(zExag=True)
  168. self.PostLightEvent()
  169. self.UpdatePage('view')
  170. self.UpdatePage('light')
  171. self.mapWindow.ReloadLayersData()
  172. self.UpdatePage('surface')
  173. self.UpdatePage('vector')
  174. self.UpdateSettings()
  175. def OnPageChanged(self, event):
  176. new = event.GetSelection()
  177. # self.ChangeSelection(new)
  178. def PostViewEvent(self, zExag=False):
  179. """Change view settings"""
  180. event = wxUpdateView(zExag=zExag)
  181. wx.PostEvent(self.mapWindow, event)
  182. def PostLightEvent(self, refresh=False):
  183. """Change light settings"""
  184. event = wxUpdateLight(refresh=refresh)
  185. wx.PostEvent(self.mapWindow, event)
  186. def OnSize(self, event):
  187. """After window is resized, update scrolling"""
  188. # workaround to resize captionbars of foldpanelbar
  189. wx.CallAfter(
  190. self.UpdateScrolling,
  191. (self.foldpanelData,
  192. self.foldpanelAppear,
  193. self.foldpanelAnalysis))
  194. event.Skip()
  195. def OnPressCaption(self, event):
  196. """When foldpanel item collapsed/expanded, update scrollbars"""
  197. foldpanel = event.GetBar().GetGrandParent().GetParent()
  198. wx.CallAfter(self.UpdateScrolling, (foldpanel,))
  199. event.Skip()
  200. def UpdateScrolling(self, foldpanels):
  201. """Update scrollbars in foldpanel"""
  202. for foldpanel in foldpanels:
  203. length = foldpanel.GetPanelsLength(collapsed=0, expanded=0)
  204. # virtual width is set to fixed value to suppress GTK warning
  205. foldpanel.GetParent().SetVirtualSize((100, length[2]))
  206. foldpanel.GetParent().Layout()
  207. def _createViewPage(self):
  208. """Create view settings page"""
  209. panel = SP.ScrolledPanel(parent=self, id=wx.ID_ANY)
  210. panel.SetupScrolling(scroll_x=False)
  211. self.page['view'] = {'id': 0,
  212. 'notebook': self.GetId()}
  213. pageSizer = wx.BoxSizer(wx.VERTICAL)
  214. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  215. label=" %s " % (_("Control View")))
  216. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  217. gridSizer = wx.GridBagSizer(vgap=5, hgap=10)
  218. self.win['view'] = {}
  219. # position
  220. posSizer = wx.GridBagSizer(vgap=3, hgap=3)
  221. self._createCompass(panel=panel, sizer=posSizer, type='view')
  222. view = ViewPositionWindow(panel, size=(175, 175),
  223. mapwindow=self.mapWindow)
  224. self.win['view']['position'] = view.GetId()
  225. posSizer.Add(
  226. item=view, pos=(1, 1),
  227. flag=wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
  228. gridSizer.Add(item=posSizer, pos=(0, 0))
  229. # perspective
  230. # set initial defaults here (or perhaps in a default values file), not in user settings
  231. # todo: consider setting an absolute max at 360 instead of undefined.
  232. # (leave the default max value at pi)
  233. tooltip = _(
  234. "Adjusts the distance and angular perspective of the image viewpoint")
  235. self._createControl(
  236. panel,
  237. data=self.win['view'],
  238. name='persp',
  239. tooltip=tooltip,
  240. range=(
  241. 1,
  242. 120),
  243. bind=(
  244. self.OnViewChange,
  245. self.OnViewChanged,
  246. self.OnViewChangedText))
  247. gridSizer.Add(
  248. item=wx.StaticText(
  249. panel, id=wx.ID_ANY, label=_("Perspective:")), pos=(
  250. 1, 0), flag=wx.ALIGN_CENTER)
  251. gridSizer.Add(
  252. item=self.FindWindowById(
  253. self.win['view']['persp']['slider']), pos=(
  254. 2, 0), flag=wx.ALIGN_CENTER)
  255. gridSizer.Add(
  256. item=self.FindWindowById(
  257. self.win['view']['persp']['text']), pos=(
  258. 3, 0), flag=wx.ALIGN_CENTER)
  259. # twist
  260. tooltip = _("Tilts the plane of the surface from the horizontal")
  261. self._createControl(panel,
  262. data=self.win['view'],
  263. name='twist',
  264. tooltip=tooltip,
  265. range=(-180,
  266. 180),
  267. bind=(self.OnViewChange,
  268. self.OnViewChanged,
  269. self.OnViewChangedText))
  270. gridSizer.Add(
  271. item=wx.StaticText(
  272. panel, id=wx.ID_ANY, label=_("Tilt:")), pos=(
  273. 1, 1), flag=wx.ALIGN_CENTER)
  274. gridSizer.Add(
  275. item=self.FindWindowById(
  276. self.win['view']['twist']['slider']), pos=(
  277. 2, 1))
  278. gridSizer.Add(
  279. item=self.FindWindowById(
  280. self.win['view']['twist']['text']), pos=(
  281. 3, 1), flag=wx.ALIGN_CENTER)
  282. # height + z-exag
  283. tooltip = _(
  284. "Adjusts the viewing height above the surface"
  285. " (angle of view automatically adjusts to maintain the same center of view)")
  286. self._createControl(
  287. panel,
  288. data=self.win['view'],
  289. name='height',
  290. sliderHor=False,
  291. tooltip=tooltip,
  292. range=(
  293. 0,
  294. 1),
  295. bind=(
  296. self.OnViewChange,
  297. self.OnViewChanged,
  298. self.OnViewChangedText))
  299. tooltip = _(
  300. "Adjusts the relative height of features above the plane of the surface")
  301. self._createControl(
  302. panel,
  303. data=self.win['view'],
  304. name='z-exag',
  305. sliderHor=False,
  306. tooltip=tooltip,
  307. range=(
  308. 0,
  309. 10),
  310. floatSlider=True,
  311. bind=(
  312. self.OnViewChange,
  313. self.OnViewChanged,
  314. self.OnViewChangedText))
  315. self.FindWindowById(self.win['view']['z-exag']['slider']).SetValue(1)
  316. self.FindWindowById(self.win['view']['z-exag']['text']).SetValue(1)
  317. heightSizer = wx.GridBagSizer(vgap=3, hgap=3)
  318. heightSizer.Add(
  319. item=wx.StaticText(
  320. panel, id=wx.ID_ANY, label=_("Height:")), pos=(
  321. 0, 0), flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, span=(
  322. 1, 2))
  323. heightSizer.Add(
  324. item=self.FindWindowById(
  325. self.win['view']['height']['slider']),
  326. flag=wx.ALIGN_RIGHT,
  327. pos=(
  328. 1,
  329. 0))
  330. heightSizer.Add(
  331. item=self.FindWindowById(
  332. self.win['view']['height']['text']),
  333. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  334. pos=(
  335. 1,
  336. 1))
  337. heightSizer.Add(
  338. item=wx.StaticText(
  339. panel,
  340. id=wx.ID_ANY,
  341. label=_("Z-exag:")),
  342. pos=(
  343. 0,
  344. 2),
  345. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL,
  346. span=(
  347. 1,
  348. 2))
  349. heightSizer.Add(
  350. item=self.FindWindowById(
  351. self.win['view']['z-exag']['slider']),
  352. flag=wx.ALIGN_RIGHT,
  353. pos=(
  354. 1,
  355. 2))
  356. heightSizer.Add(item=self.FindWindowById(
  357. self.win['view']['z-exag']['text']),
  358. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
  359. wx.BOTTOM | wx.RIGHT, pos=(1, 3))
  360. gridSizer.Add(item=heightSizer, pos=(0, 1), flag=wx.ALIGN_CENTER)
  361. # view setup + reset
  362. viewSizer = wx.BoxSizer(wx.HORIZONTAL)
  363. viewSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY,
  364. label=_("Look:")),
  365. flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
  366. border=5)
  367. here = wx.ToggleButton(panel, id=wx.ID_ANY, label=_("here"))
  368. here.Bind(wx.EVT_TOGGLEBUTTON, self.OnLookAt)
  369. here.SetName('here')
  370. here.SetToolTipString(_("Allows you to select a point on the surface "
  371. "that becomes the new center of view. "
  372. "Click on the button and then on the surface."))
  373. viewSizer.Add(item=here, flag=wx.TOP | wx.BOTTOM |
  374. wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=5)
  375. center = wx.Button(panel, id=wx.ID_ANY, label=_("center"))
  376. center.Bind(wx.EVT_BUTTON, self.OnLookAt)
  377. center.SetName('center')
  378. center.SetToolTipString(
  379. _("Resets the view to the original default center of view"))
  380. viewSizer.Add(item=center, flag=wx.TOP | wx.BOTTOM |
  381. wx.ALIGN_CENTER_VERTICAL, border=5)
  382. top = wx.Button(panel, id=wx.ID_ANY, label=_("top"))
  383. top.Bind(wx.EVT_BUTTON, self.OnLookAt)
  384. top.SetName('top')
  385. top.SetToolTipString(
  386. _("Sets the viewer directly over the scene's center position. This top view orients approximately north south."))
  387. viewSizer.Add(item=top, flag=wx.TOP | wx.BOTTOM |
  388. wx.ALIGN_CENTER_VERTICAL, border=5)
  389. reset = wx.Button(panel, id=wx.ID_ANY, label=_("reset"))
  390. reset.SetToolTipString(_("Reset to default view"))
  391. reset.Bind(wx.EVT_BUTTON, self.OnResetView)
  392. viewSizer.Add(item=reset, proportion=0,
  393. flag=wx.TOP | wx.BOTTOM | wx.RIGHT | wx.ALIGN_RIGHT,
  394. border=5)
  395. gridSizer.Add(item=viewSizer, pos=(4, 0), span=(1, 3),
  396. flag=wx.EXPAND)
  397. # body
  398. boxSizer.Add(item=gridSizer, proportion=1,
  399. flag=wx.ALL | wx.EXPAND, border=2)
  400. pageSizer.Add(item=boxSizer, proportion=0,
  401. flag=wx.EXPAND | wx.ALL,
  402. border=3)
  403. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  404. label=" %s " % (_("Image Appearance")))
  405. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  406. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  407. # background color
  408. self.win['view']['background'] = {}
  409. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  410. label=_("Background color:")),
  411. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  412. color = csel.ColourSelect(
  413. panel,
  414. id=wx.ID_ANY,
  415. colour=UserSettings.Get(
  416. group='nviz',
  417. key='view',
  418. subkey=[
  419. 'background',
  420. 'color']),
  421. size=globalvar.DIALOG_COLOR_SIZE)
  422. self.win['view']['background']['color'] = color.GetId()
  423. color.Bind(csel.EVT_COLOURSELECT, self.OnBgColor)
  424. gridSizer.Add(item=color, pos=(0, 1))
  425. gridSizer.AddGrowableCol(0)
  426. boxSizer.Add(item=gridSizer, proportion=1,
  427. flag=wx.ALL | wx.EXPAND, border=3)
  428. pageSizer.Add(item=boxSizer, proportion=0,
  429. flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
  430. border=3)
  431. panel.SetSizer(pageSizer)
  432. return panel
  433. def _createAnimationPage(self):
  434. """Create view settings page"""
  435. panel = SP.ScrolledPanel(parent=self, id=wx.ID_ANY)
  436. panel.SetupScrolling(scroll_x=False)
  437. self.page['animation'] = {'id': 0,
  438. 'notebook': self.GetId()}
  439. pageSizer = wx.BoxSizer(wx.VERTICAL)
  440. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  441. label=" %s " % (_("Animation")))
  442. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  443. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  444. self.win['anim'] = {}
  445. # animation help text
  446. help = wx.StaticText(
  447. parent=panel, id=wx.ID_ANY, label=_(
  448. "Press 'Record' button and start changing the view. "
  449. "It is recommended to use fly-through mode "
  450. "(Map Display toolbar) to achieve smooth motion."))
  451. self.win['anim']['help'] = help.GetId()
  452. hSizer.Add(item=help, proportion=0)
  453. boxSizer.Add(item=hSizer, proportion=1,
  454. flag=wx.ALL | wx.EXPAND, border=5)
  455. # animation controls
  456. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  457. record = SymbolButton(parent=panel, id=wx.ID_ANY,
  458. usage="record", label=_("Record"))
  459. play = SymbolButton(parent=panel, id=wx.ID_ANY,
  460. usage="play", label=_("Play"))
  461. pause = SymbolButton(parent=panel, id=wx.ID_ANY,
  462. usage="pause", label=_("Pause"))
  463. stop = SymbolButton(parent=panel, id=wx.ID_ANY,
  464. usage="stop", label=_("Stop"))
  465. self.win['anim']['record'] = record.GetId()
  466. self.win['anim']['play'] = play.GetId()
  467. self.win['anim']['pause'] = pause.GetId()
  468. self.win['anim']['stop'] = stop.GetId()
  469. self._createControl(
  470. panel, data=self.win['anim'], name='frameIndex', range=(
  471. 0, 1), floatSlider=False, bind=(
  472. self.OnFrameIndex, None, self.OnFrameIndexText))
  473. frameSlider = self.FindWindowById(
  474. self.win['anim']['frameIndex']['slider'])
  475. frameText = self.FindWindowById(self.win['anim']['frameIndex']['text'])
  476. infoLabel = wx.StaticText(
  477. parent=panel,
  478. id=wx.ID_ANY,
  479. label=_("Total number of frames :"))
  480. info = wx.StaticText(parent=panel, id=wx.ID_ANY)
  481. self.win['anim']['info'] = info.GetId()
  482. fpsLabel = wx.StaticText(
  483. parent=panel,
  484. id=wx.ID_ANY,
  485. label=_("Frame rate (FPS):"))
  486. fps = wx.SpinCtrl(
  487. parent=panel, id=wx.ID_ANY, size=(65, -1),
  488. initial=UserSettings.Get(
  489. group='nviz', key='animation', subkey='fps'),
  490. min=1, max=50)
  491. self.win['anim']['fps'] = fps.GetId()
  492. fps.SetToolTipString(
  493. _("Frames are recorded with given frequency (FPS). "))
  494. record.Bind(wx.EVT_BUTTON, self.OnRecord)
  495. play.Bind(wx.EVT_BUTTON, self.OnPlay)
  496. stop.Bind(wx.EVT_BUTTON, self.OnStop)
  497. pause.Bind(wx.EVT_BUTTON, self.OnPause)
  498. fps.Bind(wx.EVT_SPINCTRL, self.OnFPS)
  499. hSizer.Add(item=record, proportion=0)
  500. hSizer.Add(item=play, proportion=0)
  501. hSizer.Add(item=pause, proportion=0)
  502. hSizer.Add(item=stop, proportion=0)
  503. boxSizer.Add(item=hSizer, proportion=0,
  504. flag=wx.ALL | wx.EXPAND, border=3)
  505. sliderBox = wx.BoxSizer(wx.HORIZONTAL)
  506. sliderBox.Add(
  507. item=frameSlider,
  508. proportion=1,
  509. border=5,
  510. flag=wx.EXPAND | wx.RIGHT)
  511. sliderBox.Add(
  512. item=frameText,
  513. proportion=0,
  514. border=5,
  515. flag=wx.EXPAND | wx.RIGHT | wx.LEFT)
  516. boxSizer.Add(item=sliderBox, proportion=0, flag=wx.EXPAND)
  517. # total number of frames
  518. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  519. hSizer.Add(item=infoLabel, proportion=0, flag=wx.RIGHT, border=5)
  520. hSizer.Add(item=info, proportion=0, flag=wx.LEFT, border=5)
  521. boxSizer.Add(item=hSizer, proportion=0,
  522. flag=wx.ALL | wx.EXPAND, border=5)
  523. # frames per second
  524. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  525. hSizer.Add(
  526. item=fpsLabel,
  527. proportion=0,
  528. flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
  529. border=5)
  530. hSizer.Add(item=fps, proportion=0, flag=wx.LEFT |
  531. wx.ALIGN_CENTER_VERTICAL, border=5)
  532. boxSizer.Add(item=hSizer, proportion=0,
  533. flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
  534. pageSizer.Add(item=boxSizer, proportion=0,
  535. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  536. border=3)
  537. # save animation
  538. self.win['anim']['save'] = {}
  539. self.win['anim']['save']['image'] = {}
  540. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  541. label=" %s " % (_("Save image sequence")))
  542. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  543. vSizer = wx.BoxSizer(wx.VERTICAL)
  544. gridSizer = wx.GridBagSizer(vgap=5, hgap=10)
  545. pwd = os.getcwd()
  546. dir = filebrowse.DirBrowseButton(
  547. parent=panel,
  548. id=wx.ID_ANY,
  549. labelText=_("Choose a directory:"),
  550. dialogTitle=_("Choose a directory for images"),
  551. buttonText=_('Browse'),
  552. startDirectory=pwd)
  553. dir.SetValue(pwd)
  554. prefixLabel = wx.StaticText(
  555. parent=panel,
  556. id=wx.ID_ANY,
  557. label=_("File prefix:"))
  558. prefixCtrl = wx.TextCtrl(
  559. parent=panel, id=wx.ID_ANY, size=(100, -1),
  560. value=UserSettings.Get(
  561. group='nviz', key='animation', subkey='prefix'))
  562. prefixCtrl.SetToolTipString(
  563. _("Generated files names will look like this: prefix_1.ppm, prefix_2.ppm, ..."))
  564. fileTypeLabel = wx.StaticText(
  565. parent=panel, id=wx.ID_ANY, label=_("File format:"))
  566. fileTypeCtrl = wx.Choice(
  567. parent=panel, id=wx.ID_ANY, choices=[
  568. "TIF", "PPM"])
  569. save = wx.Button(parent=panel, id=wx.ID_ANY,
  570. label="Save")
  571. self.win['anim']['save']['image']['dir'] = dir.GetId()
  572. self.win['anim']['save']['image']['prefix'] = prefixCtrl.GetId()
  573. self.win['anim']['save']['image']['format'] = fileTypeCtrl.GetId()
  574. self.win['anim']['save']['image']['confirm'] = save.GetId()
  575. boxSizer.Add(item=dir, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
  576. gridSizer.Add(
  577. item=prefixLabel, pos=(0, 0),
  578. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  579. gridSizer.Add(item=prefixCtrl, pos=(0, 1), flag=wx.EXPAND)
  580. gridSizer.Add(
  581. item=fileTypeLabel, pos=(1, 0),
  582. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  583. gridSizer.Add(item=fileTypeCtrl, pos=(1, 1), flag=wx.EXPAND)
  584. boxSizer.Add(item=gridSizer, proportion=1,
  585. flag=wx.ALL | wx.EXPAND, border=5)
  586. boxSizer.Add(
  587. item=save,
  588. proportion=0,
  589. flag=wx.ALL | wx.ALIGN_RIGHT,
  590. border=5)
  591. save.Bind(wx.EVT_BUTTON, self.OnSaveAnimation)
  592. pageSizer.Add(item=boxSizer, proportion=0,
  593. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  594. border=3)
  595. panel.SetSizer(pageSizer)
  596. return panel
  597. def _createDataPage(self):
  598. """Create data (surface, vector, volume) settings page"""
  599. self.mainPanelData = ScrolledPanel(parent=self)
  600. self.mainPanelData.SetupScrolling(scroll_x=False)
  601. try: # wxpython <= 2.8.10
  602. self.foldpanelData = fpb.FoldPanelBar(
  603. parent=self.mainPanelData, id=wx.ID_ANY,
  604. style=fpb.FPB_DEFAULT_STYLE, extraStyle=fpb.FPB_SINGLE_FOLD)
  605. except:
  606. try: # wxpython >= 2.8.11
  607. self.foldpanelData = fpb.FoldPanelBar(
  608. parent=self.mainPanelData, id=wx.ID_ANY,
  609. agwStyle=fpb.FPB_SINGLE_FOLD)
  610. except: # to be sure
  611. self.foldpanelData = fpb.FoldPanelBar(
  612. parent=self.mainPanelData, id=wx.ID_ANY,
  613. style=fpb.FPB_SINGLE_FOLD)
  614. self.foldpanelData.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
  615. # # surface page
  616. surfacePanel = self.foldpanelData.AddFoldPanel(
  617. _("Surface"), collapsed=False)
  618. self.foldpanelData.AddFoldPanelWindow(
  619. surfacePanel, window=self._createSurfacePage(
  620. parent=surfacePanel), flags=fpb.FPB_ALIGN_WIDTH)
  621. self.EnablePage("surface", enabled=False)
  622. # constant page
  623. constantPanel = self.foldpanelData.AddFoldPanel(
  624. _("Constant surface"), collapsed=True)
  625. self.foldpanelData.AddFoldPanelWindow(
  626. constantPanel, window=self._createConstantPage(
  627. parent=constantPanel), flags=fpb.FPB_ALIGN_WIDTH)
  628. self.EnablePage("constant", enabled=False)
  629. # vector page
  630. vectorPanel = self.foldpanelData.AddFoldPanel(
  631. _("Vector"), collapsed=True)
  632. self.foldpanelData.AddFoldPanelWindow(
  633. vectorPanel, window=self._createVectorPage(
  634. parent=vectorPanel), flags=fpb.FPB_ALIGN_WIDTH)
  635. self.EnablePage("vector", enabled=False)
  636. # volume page
  637. volumePanel = self.foldpanelData.AddFoldPanel(
  638. _("3D raster"), collapsed=True)
  639. self.foldpanelData.AddFoldPanelWindow(
  640. volumePanel, window=self._createVolumePage(
  641. parent=volumePanel), flags=fpb.FPB_ALIGN_WIDTH)
  642. self.EnablePage("volume", enabled=False)
  643. # self.foldpanelData.ApplyCaptionStyleAll(style)
  644. sizer = wx.BoxSizer(wx.VERTICAL)
  645. sizer.Add(self.foldpanelData, proportion=1, flag=wx.EXPAND)
  646. self.mainPanelData.SetSizer(sizer)
  647. self.mainPanelData.Layout()
  648. self.mainPanelData.Fit()
  649. return self.mainPanelData
  650. def _createAppearancePage(self):
  651. """Create data (surface, vector, volume) settings page"""
  652. self.mainPanelAppear = ScrolledPanel(parent=self)
  653. self.mainPanelAppear.SetupScrolling(scroll_x=False)
  654. try: # wxpython <= 2.8.10
  655. self.foldpanelAppear = fpb.FoldPanelBar(
  656. parent=self.mainPanelAppear, id=wx.ID_ANY,
  657. style=fpb.FPB_DEFAULT_STYLE, extraStyle=fpb.FPB_SINGLE_FOLD)
  658. except:
  659. try: # wxpython >= 2.8.11
  660. self.foldpanelAppear = fpb.FoldPanelBar(
  661. parent=self.mainPanelAppear, id=wx.ID_ANY,
  662. agwStyle=fpb.FPB_SINGLE_FOLD)
  663. except: # to be sure
  664. self.foldpanelAppear = fpb.FoldPanelBar(
  665. parent=self.mainPanelAppear, id=wx.ID_ANY,
  666. style=fpb.FPB_SINGLE_FOLD)
  667. self.foldpanelAppear.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
  668. # light page
  669. lightPanel = self.foldpanelAppear.AddFoldPanel(
  670. _("Lighting"), collapsed=False)
  671. self.foldpanelAppear.AddFoldPanelWindow(
  672. lightPanel, window=self._createLightPage(
  673. parent=lightPanel), flags=fpb.FPB_ALIGN_WIDTH)
  674. # fringe page
  675. fringePanel = self.foldpanelAppear.AddFoldPanel(
  676. _("Fringe"), collapsed=True)
  677. self.foldpanelAppear.AddFoldPanelWindow(
  678. fringePanel, window=self._createFringePage(
  679. parent=fringePanel), flags=fpb.FPB_ALIGN_WIDTH)
  680. self.EnablePage('fringe', False)
  681. # decoration page
  682. decorationPanel = self.foldpanelAppear.AddFoldPanel(
  683. _("Decorations"), collapsed=True)
  684. self.foldpanelAppear.AddFoldPanelWindow(
  685. decorationPanel, window=self._createDecorationPage(
  686. parent=decorationPanel), flags=fpb.FPB_ALIGN_WIDTH)
  687. sizer = wx.BoxSizer(wx.VERTICAL)
  688. sizer.Add(self.foldpanelAppear, proportion=1, flag=wx.EXPAND)
  689. self.mainPanelAppear.SetSizer(sizer)
  690. self.mainPanelAppear.Layout()
  691. self.mainPanelAppear.Fit()
  692. return self.mainPanelAppear
  693. def _createAnalysisPage(self):
  694. """Create data analysis (cutting planes, ...) page"""
  695. self.mainPanelAnalysis = ScrolledPanel(parent=self)
  696. self.mainPanelAnalysis.SetupScrolling(scroll_x=False)
  697. self.foldpanelAnalysis = fpb.FoldPanelBar(
  698. parent=self.mainPanelAnalysis, id=wx.ID_ANY,
  699. style=fpb.FPB_SINGLE_FOLD)
  700. self.foldpanelAnalysis.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
  701. # cutting planes page
  702. cplanePanel = self.foldpanelAnalysis.AddFoldPanel(
  703. _("Cutting planes"), collapsed=False)
  704. self.foldpanelAnalysis.AddFoldPanelWindow(
  705. cplanePanel, window=self._createCPlanePage(
  706. parent=cplanePanel), flags=fpb.FPB_ALIGN_WIDTH)
  707. sizer = wx.BoxSizer(wx.VERTICAL)
  708. sizer.Add(self.foldpanelAnalysis, proportion=1, flag=wx.EXPAND)
  709. self.mainPanelAnalysis.SetSizer(sizer)
  710. self.mainPanelAnalysis.Layout()
  711. self.mainPanelAnalysis.Fit()
  712. return self.mainPanelAnalysis
  713. def _createSurfacePage(self, parent):
  714. """Create view settings page"""
  715. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  716. self.page['surface'] = {'id': 0,
  717. 'notebook': self.foldpanelData.GetId()}
  718. pageSizer = wx.BoxSizer(wx.VERTICAL)
  719. self.win['surface'] = {}
  720. # selection
  721. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  722. label=" %s " % (_("Raster map")))
  723. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  724. rmaps = Select(parent=panel, type='raster',
  725. onPopup=self.GselectOnPopup)
  726. rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetRaster)
  727. self.win['surface']['map'] = rmaps.GetId()
  728. desc = wx.StaticText(parent=panel, id=wx.ID_ANY)
  729. self.win['surface']['desc'] = desc.GetId()
  730. boxSizer.Add(item=rmaps, proportion=0,
  731. flag=wx.ALL,
  732. border=3)
  733. boxSizer.Add(item=desc, proportion=0,
  734. flag=wx.ALL,
  735. border=3)
  736. pageSizer.Add(item=boxSizer, proportion=0,
  737. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  738. border=3)
  739. #
  740. # draw
  741. #
  742. self.win['surface']['draw'] = {}
  743. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  744. label=" %s " % (_("Draw")))
  745. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  746. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  747. # mode
  748. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  749. label=_("Mode:")),
  750. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  751. mode = wx.Choice(parent=panel, id=wx.ID_ANY, size=(-1, -1),
  752. choices=[_("coarse"),
  753. _("fine"),
  754. _("both")])
  755. mode.SetName("selection")
  756. mode.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  757. self.win['surface']['draw']['mode'] = mode.GetId()
  758. gridSizer.Add(item=mode, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  759. pos=(0, 1), span=(1, 2))
  760. # shading
  761. gridSizer.Add(
  762. item=wx.StaticText(
  763. parent=panel, id=wx.ID_ANY, label=_("Shading:")), pos=(
  764. 0, 3), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
  765. shade = wx.Choice(parent=panel, id=wx.ID_ANY, size=(-1, -1),
  766. choices=[_("flat"),
  767. _("gouraud")])
  768. shade.SetName("selection")
  769. self.win['surface']['draw']['shading'] = shade.GetId()
  770. shade.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  771. gridSizer.Add(item=shade, flag=wx.ALIGN_CENTER_VERTICAL,
  772. pos=(0, 4))
  773. # set to all
  774. all = wx.Button(panel, id=wx.ID_ANY, label=_("Set to all"))
  775. all.SetToolTipString(_("Use draw settings for all loaded surfaces"))
  776. all.Bind(wx.EVT_BUTTON, self.OnSurfaceModeAll)
  777. gridSizer.Add(
  778. item=all,
  779. flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  780. pos=(
  781. 3,
  782. 4))
  783. self.win['surface']['all'] = all.GetId()
  784. # resolution coarse
  785. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  786. label=_("Coarse mode:")),
  787. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  788. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  789. label=_("resolution:")),
  790. pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  791. resC = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  792. initial=6,
  793. min=1,
  794. max=100)
  795. resC.SetName("value")
  796. self.win['surface']['draw']['res-coarse'] = resC.GetId()
  797. resC.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
  798. gridSizer.Add(
  799. item=resC, pos=(2, 2),
  800. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
  801. # Coarse style
  802. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  803. label=_("style:")),
  804. pos=(3, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  805. style = wx.Choice(parent=panel, id=wx.ID_ANY, size=(100, -1),
  806. choices=[_("wire"),
  807. _("surface")])
  808. style.SetName("selection")
  809. self.win['surface']['draw']['style'] = style.GetId()
  810. style.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  811. gridSizer.Add(item=style, flag=wx.ALIGN_CENTER_VERTICAL,
  812. pos=(3, 2))
  813. # color
  814. color = csel.ColourSelect(panel, id=wx.ID_ANY,
  815. size=globalvar.DIALOG_COLOR_SIZE)
  816. color.SetName("colour")
  817. color.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceWireColor)
  818. color.SetToolTipString(_("Change wire color"))
  819. self.win['surface']['draw']['wire-color'] = color.GetId()
  820. gridSizer.Add(
  821. item=color,
  822. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  823. pos=(
  824. 3,
  825. 3))
  826. # resolution fine
  827. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  828. label=_("Fine mode:")),
  829. pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  830. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  831. label=_("resolution:")),
  832. pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  833. resF = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  834. initial=3,
  835. min=1,
  836. max=100)
  837. resF.SetName("value")
  838. self.win['surface']['draw']['res-fine'] = resF.GetId()
  839. resF.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
  840. gridSizer.Add(
  841. item=resF, pos=(1, 2),
  842. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
  843. gridSizer.AddGrowableCol(3)
  844. boxSizer.Add(item=gridSizer, proportion=1,
  845. flag=wx.ALL | wx.EXPAND, border=3)
  846. pageSizer.Add(item=boxSizer, proportion=0,
  847. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  848. border=3)
  849. #
  850. # surface attributes
  851. #
  852. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  853. label=" %s " % (_("Surface attributes")))
  854. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  855. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  856. # type
  857. self.win['surface']['attr'] = {}
  858. row = 0
  859. for code, attrb in (('color', _("Color")),
  860. ('mask', _("Mask")),
  861. ('transp', _("Transparency")),
  862. ('shine', _("Shininess"))):
  863. self.win['surface'][code] = {}
  864. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  865. label=attrb + ':'),
  866. pos=(row, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  867. use = wx.Choice(parent=panel, id=wx.ID_ANY, size=(100, -1),
  868. choices=[_("map")])
  869. if code not in ('color', 'shine'):
  870. use.Insert(item=_("unset"), pos=0)
  871. self.win['surface'][code]['required'] = False
  872. else:
  873. self.win['surface'][code]['required'] = True
  874. if code != 'mask':
  875. use.Append(item=_('constant'))
  876. self.win['surface'][code]['use'] = use.GetId()
  877. use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
  878. gridSizer.Add(item=use, flag=wx.ALIGN_CENTER_VERTICAL,
  879. pos=(row, 1))
  880. map = Select(parent=panel, id=wx.ID_ANY,
  881. # size = globalvar.DIALOG_GSELECT_SIZE,
  882. size=(-1, -1),
  883. type="raster")
  884. if globalvar.CheckWxVersion([3]):
  885. self.win['surface'][code]['map'] = map.GetId()
  886. else:
  887. self.win['surface'][code]['map'] = map.GetTextCtrl().GetId()
  888. map.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
  889. gridSizer.Add(item=map, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  890. pos=(row, 2))
  891. if code == 'color':
  892. color = UserSettings.Get(
  893. group='nviz', key='surface', subkey=[
  894. 'color', 'value'])
  895. value = csel.ColourSelect(panel, id=wx.ID_ANY,
  896. colour=color,
  897. size=globalvar.DIALOG_COLOR_SIZE)
  898. value.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceMap)
  899. elif code == 'mask':
  900. value = None
  901. else:
  902. value = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  903. initial=0)
  904. value.SetRange(minVal=0, maxVal=100)
  905. value.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
  906. if value:
  907. self.win['surface'][code]['const'] = value.GetId()
  908. value.Enable(False)
  909. gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL,
  910. pos=(row, 3))
  911. else:
  912. self.win['surface'][code]['const'] = None
  913. # -> enable map / disable constant
  914. self.SetMapObjUseMap(nvizType='surface', attrb=code)
  915. row += 1
  916. gridSizer.AddGrowableCol(2)
  917. boxSizer.Add(item=gridSizer, proportion=0,
  918. flag=wx.ALL | wx.EXPAND, border=3)
  919. pageSizer.Add(item=boxSizer, proportion=0,
  920. flag=wx.EXPAND | wx.ALL,
  921. border=3)
  922. #
  923. # position
  924. #
  925. self.win['surface']['position'] = {}
  926. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  927. label=" %s " % (_("Position")))
  928. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  929. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  930. # position
  931. tooltip = _("Changes the x, y, and z position of the current surface")
  932. self._createControl(panel,
  933. data=self.win['surface'],
  934. name='position',
  935. tooltip=tooltip,
  936. range=(-10000,
  937. 10000),
  938. floatSlider=True,
  939. bind=(self.OnSurfacePosition,
  940. self.OnSurfacePositionChanged,
  941. self.OnSurfacePositionText))
  942. axis = wx.Choice(parent=panel, id=wx.ID_ANY, size=(75, -1),
  943. choices=["X",
  944. "Y",
  945. "Z"])
  946. reset = wx.Button(panel, id=wx.ID_ANY, label=_("Reset"))
  947. reset.SetToolTipString(_("Reset to default position"))
  948. reset.Bind(wx.EVT_BUTTON, self.OnResetSurfacePosition)
  949. self.win['surface']['position']['reset'] = reset.GetId()
  950. self.win['surface']['position']['axis'] = axis.GetId()
  951. axis.SetSelection(2)
  952. axis.Bind(wx.EVT_CHOICE, self.OnSurfaceAxis)
  953. pslide = self.FindWindowById(self.win['surface']['position']['slider'])
  954. ptext = self.FindWindowById(self.win['surface']['position']['text'])
  955. ptext.SetValue('0')
  956. gridSizer.Add(item=axis, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
  957. gridSizer.Add(item=pslide, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 1))
  958. gridSizer.Add(item=ptext, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 2))
  959. gridSizer.Add(
  960. item=reset,
  961. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  962. pos=(
  963. 0,
  964. 3))
  965. gridSizer.AddGrowableCol(3)
  966. boxSizer.Add(item=gridSizer, proportion=1,
  967. flag=wx.ALL | wx.EXPAND, border=3)
  968. pageSizer.Add(item=boxSizer, proportion=1,
  969. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  970. border=3)
  971. #
  972. # mask
  973. #
  974. # box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  975. # label = " %s " % (_("Mask")))
  976. ## boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  977. ## gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  978. ##
  979. # gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  980. # label = _("Mask zeros:")),
  981. # pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  982. ##
  983. # elev = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  984. # label = _("by elevation"))
  985. # elev.Enable(False) # TODO: not implemented yet
  986. ## gridSizer.Add(item = elev, pos = (0, 1))
  987. ##
  988. # color = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  989. # label = _("by color"))
  990. # color.Enable(False) # TODO: not implemented yet
  991. ## gridSizer.Add(item = color, pos = (0, 2))
  992. ##
  993. # boxSizer.Add(item = gridSizer, proportion = 1,
  994. # flag = wx.ALL | wx.EXPAND, border = 3)
  995. # pageSizer.Add(item = boxSizer, proportion = 0,
  996. ## flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  997. # border = 3)
  998. panel.SetSizer(pageSizer)
  999. panel.Layout()
  1000. panel.Fit()
  1001. return panel
  1002. def _createCPlanePage(self, parent):
  1003. """Create cutting planes page"""
  1004. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  1005. self.page['cplane'] = {'id': 4,
  1006. 'notebook': self.foldpanelData.GetId()}
  1007. self.win['cplane'] = {}
  1008. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1009. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1010. label=" %s " % (_("Cutting planes")))
  1011. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1012. horSizer = wx.BoxSizer(wx.HORIZONTAL)
  1013. # planes
  1014. horSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1015. label=_("Active cutting plane:")),
  1016. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
  1017. choice = wx.Choice(parent=panel, id=wx.ID_ANY, choices=[])
  1018. self.win['cplane']['planes'] = choice.GetId()
  1019. choice.Bind(wx.EVT_CHOICE, self.OnCPlaneSelection)
  1020. horSizer.Add(item=choice, flag=wx.ALL, border=5)
  1021. # shading
  1022. horSizer.Add(item=wx.Size(-1, -1), proportion=1)
  1023. horSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1024. label=_("Shading:")),
  1025. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
  1026. choices = [_("clear"),
  1027. _("top color"),
  1028. _("bottom color"),
  1029. _("blend"),
  1030. _("shaded")]
  1031. choice = wx.Choice(parent=panel, id=wx.ID_ANY, choices=choices)
  1032. self.win['cplane']['shading'] = choice.GetId()
  1033. choice.Bind(wx.EVT_CHOICE, self.OnCPlaneShading)
  1034. horSizer.Add(item=choice, flag=wx.ALL, border=5)
  1035. boxSizer.Add(item=horSizer, flag=wx.EXPAND)
  1036. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  1037. # cutting plane horizontal x position
  1038. self.win['cplane']['position'] = {}
  1039. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1040. label=_("Horizontal X:")),
  1041. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1042. tooltip = _("Sets the X coordinate of the current cutting plane")
  1043. self._createControl(panel,
  1044. data=self.win['cplane']['position'],
  1045. name='x',
  1046. size=250,
  1047. range=(-1000,
  1048. 1000),
  1049. sliderHor=True,
  1050. floatSlider=True,
  1051. tooltip=tooltip,
  1052. bind=(self.OnCPlaneChanging,
  1053. self.OnCPlaneChangeDone,
  1054. self.OnCPlaneChangeText))
  1055. self.FindWindowById(self.win['cplane']['position'][
  1056. 'x']['slider']).SetValue(0)
  1057. self.FindWindowById(self.win['cplane']['position'][
  1058. 'x']['text']).SetValue(0)
  1059. gridSizer.Add(
  1060. item=self.FindWindowById(
  1061. self.win['cplane']['position']['x']['slider']), pos=(
  1062. 0, 1), flag=wx.EXPAND | wx.ALIGN_RIGHT)
  1063. gridSizer.Add(
  1064. item=self.FindWindowById(
  1065. self.win['cplane']['position']['x']['text']), pos=(
  1066. 0, 2), flag=wx.ALIGN_CENTER)
  1067. # cutting plane horizontal y position
  1068. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1069. label=_("Horizontal Y:")),
  1070. pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1071. tooltip = _("Sets the Y coordinate of the current cutting plane")
  1072. self._createControl(panel,
  1073. data=self.win['cplane']['position'],
  1074. name='y',
  1075. size=250,
  1076. range=(-1000,
  1077. 1000),
  1078. sliderHor=True,
  1079. floatSlider=True,
  1080. tooltip=tooltip,
  1081. bind=(self.OnCPlaneChanging,
  1082. self.OnCPlaneChangeDone,
  1083. self.OnCPlaneChangeText))
  1084. self.FindWindowById(self.win['cplane']['position'][
  1085. 'y']['slider']).SetValue(0)
  1086. self.FindWindowById(self.win['cplane']['position'][
  1087. 'y']['text']).SetValue(0)
  1088. gridSizer.Add(
  1089. item=self.FindWindowById(
  1090. self.win['cplane']['position']['y']['slider']), pos=(
  1091. 1, 1), flag=wx.EXPAND | wx.ALIGN_RIGHT)
  1092. gridSizer.Add(
  1093. item=self.FindWindowById(
  1094. self.win['cplane']['position']['y']['text']), pos=(
  1095. 1, 2), flag=wx.ALIGN_CENTER)
  1096. # cutting plane rotation
  1097. self.win['cplane']['rotation'] = {}
  1098. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1099. label=_("Rotation:")),
  1100. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1101. tooltip = _("Rotates the current cutting plane about vertical axis")
  1102. self._createControl(
  1103. panel, data=self.win['cplane']['rotation'], name='rot', size=250, range=(
  1104. 0, 360), sliderHor=True, tooltip=tooltip, bind=(
  1105. self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
  1106. self.FindWindowById(self.win['cplane']['rotation'][
  1107. 'rot']['slider']).SetValue(180)
  1108. self.FindWindowById(self.win['cplane']['rotation'][
  1109. 'rot']['text']).SetValue(180)
  1110. gridSizer.Add(
  1111. item=self.FindWindowById(
  1112. self.win['cplane']['rotation']['rot']['slider']), pos=(
  1113. 2, 1), flag=wx.EXPAND | wx.ALIGN_RIGHT)
  1114. gridSizer.Add(
  1115. item=self.FindWindowById(
  1116. self.win['cplane']['rotation']['rot']['text']), pos=(
  1117. 2, 2), flag=wx.ALIGN_CENTER)
  1118. # cutting plane tilt
  1119. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1120. label=_("Tilt:")),
  1121. pos=(3, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1122. tooltip = _("Rotates the current cutting plane about horizontal axis")
  1123. self._createControl(
  1124. panel, data=self.win['cplane']['rotation'], name='tilt', size=250, range=(
  1125. 0, 360), sliderHor=True, tooltip=tooltip, bind=(
  1126. self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
  1127. self.FindWindowById(self.win['cplane']['rotation'][
  1128. 'tilt']['slider']).SetValue(0)
  1129. self.FindWindowById(self.win['cplane']['rotation'][
  1130. 'tilt']['text']).SetValue(0)
  1131. gridSizer.Add(
  1132. item=self.FindWindowById(
  1133. self.win['cplane']['rotation']['tilt']['slider']), pos=(
  1134. 3, 1), flag=wx.EXPAND | wx.ALIGN_RIGHT)
  1135. gridSizer.Add(
  1136. item=self.FindWindowById(
  1137. self.win['cplane']['rotation']['tilt']['text']), pos=(
  1138. 3, 2), flag=wx.ALIGN_CENTER)
  1139. # cutting pland height
  1140. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1141. label=_("Height:")),
  1142. pos=(4, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1143. tooltip = _(
  1144. "Sets the Z coordinate of the current cutting plane (only meaningful when tilt is not 0)")
  1145. self._createControl(panel,
  1146. data=self.win['cplane']['position'],
  1147. name='z',
  1148. size=250,
  1149. range=(-1000,
  1150. 1000),
  1151. sliderHor=True,
  1152. tooltip=tooltip,
  1153. bind=(self.OnCPlaneChanging,
  1154. self.OnCPlaneChangeDone,
  1155. self.OnCPlaneChangeText))
  1156. self.FindWindowById(self.win['cplane']['position'][
  1157. 'z']['slider']).SetValue(0)
  1158. self.FindWindowById(self.win['cplane']['position'][
  1159. 'z']['text']).SetValue(0)
  1160. gridSizer.Add(
  1161. item=self.FindWindowById(
  1162. self.win['cplane']['position']['z']['slider']), pos=(
  1163. 4, 1), flag=wx.EXPAND | wx.ALIGN_RIGHT)
  1164. gridSizer.Add(
  1165. item=self.FindWindowById(
  1166. self.win['cplane']['position']['z']['text']), pos=(
  1167. 4, 2), flag=wx.ALIGN_CENTER)
  1168. boxSizer.Add(
  1169. gridSizer,
  1170. proportion=0,
  1171. flag=wx.EXPAND | wx.ALL,
  1172. border=5)
  1173. horSizer = wx.BoxSizer(wx.HORIZONTAL)
  1174. horSizer.Add(item=wx.Size(-1, -1), proportion=1, flag=wx.ALL, border=5)
  1175. # reset
  1176. reset = wx.Button(parent=panel, id=wx.ID_ANY, label=_("Reset"))
  1177. self.win['cplane']['reset'] = reset.GetId()
  1178. reset.Bind(wx.EVT_BUTTON, self.OnCPlaneReset)
  1179. horSizer.Add(item=reset, flag=wx.ALL, border=5)
  1180. boxSizer.Add(horSizer, proportion=0, flag=wx.EXPAND)
  1181. pageSizer.Add(boxSizer, proportion=0, flag=wx.EXPAND)
  1182. panel.SetSizer(pageSizer)
  1183. panel.Fit()
  1184. return panel
  1185. def _createConstantPage(self, parent):
  1186. """Create constant page"""
  1187. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  1188. self.page['constant'] = {'id': 1,
  1189. 'notebook': self.foldpanelData.GetId()}
  1190. self.win['constant'] = {}
  1191. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1192. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1193. label=" %s " % (_("Constant surface")))
  1194. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1195. horsizer = wx.BoxSizer(wx.HORIZONTAL)
  1196. surface = wx.ComboBox(parent=panel, id=wx.ID_ANY,
  1197. style=wx.CB_SIMPLE | wx.CB_READONLY,
  1198. choices=[])
  1199. self.win['constant']['surface'] = surface.GetId()
  1200. surface.Bind(wx.EVT_COMBOBOX, self.OnConstantSelection)
  1201. horsizer.Add(
  1202. surface,
  1203. proportion=1,
  1204. flag=wx.EXPAND | wx.RIGHT,
  1205. border=20)
  1206. addNew = wx.Button(panel, id=wx.ID_ANY, label=_("New"))
  1207. addNew.Bind(wx.EVT_BUTTON, self.OnNewConstant)
  1208. self.win['constant']['new'] = addNew.GetId()
  1209. delete = wx.Button(panel, id=wx.ID_ANY, label=_("Delete"))
  1210. delete.Bind(wx.EVT_BUTTON, self.OnDeleteConstant)
  1211. self.win['constant']['delete'] = delete.GetId()
  1212. horsizer.Add(
  1213. item=addNew,
  1214. proportion=0,
  1215. flag=wx.RIGHT | wx.LEFT,
  1216. border=3)
  1217. horsizer.Add(
  1218. item=delete,
  1219. proportion=0,
  1220. flag=wx.RIGHT | wx.LEFT,
  1221. border=3)
  1222. boxSizer.Add(item=horsizer, proportion=0, flag=wx.ALL | wx.EXPAND,
  1223. border=5)
  1224. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  1225. # fine resolution
  1226. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1227. label=_("Fine resolution:")),
  1228. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1229. resF = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1230. initial=3,
  1231. min=1,
  1232. max=100)
  1233. resF.SetName("value")
  1234. self.win['constant']['resolution'] = resF.GetId()
  1235. resF.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
  1236. gridSizer.Add(
  1237. item=resF, pos=(0, 1),
  1238. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
  1239. # value
  1240. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1241. label=_("Value:")), pos=(1, 0),
  1242. flag=wx.ALIGN_CENTER_VERTICAL)
  1243. value = wx.SpinCtrl(panel, id=wx.ID_ANY,
  1244. min=-1e9, max=1e9,
  1245. size=(65, -1))
  1246. self.win['constant']['value'] = value.GetId()
  1247. value.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
  1248. gridSizer.Add(item=value, pos=(1, 1))
  1249. # transparency
  1250. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1251. label=_("Transparency:")), pos=(2, 0),
  1252. flag=wx.ALIGN_CENTER_VERTICAL)
  1253. transp = wx.SpinCtrl(panel, id=wx.ID_ANY,
  1254. min=0, max=100,
  1255. size=(65, -1))
  1256. self.win['constant']['transp'] = transp.GetId()
  1257. transp.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
  1258. gridSizer.Add(item=transp, pos=(2, 1))
  1259. # color
  1260. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1261. label=_("Color:")), pos=(3, 0),
  1262. flag=wx.ALIGN_CENTER_VERTICAL)
  1263. color = csel.ColourSelect(panel, id=wx.ID_ANY,
  1264. colour=(0, 0, 0),
  1265. size=globalvar.DIALOG_COLOR_SIZE)
  1266. self.win['constant']['color'] = color.GetId()
  1267. color.Bind(csel.EVT_COLOURSELECT, self.OnSetConstantProp)
  1268. gridSizer.Add(item=color, pos=(3, 1))
  1269. boxSizer.Add(item=gridSizer, proportion=0, flag=wx.ALL,
  1270. border=5)
  1271. pageSizer.Add(item=boxSizer, proportion=0,
  1272. flag=wx.EXPAND | wx.ALL,
  1273. border=3)
  1274. panel.SetSizer(pageSizer)
  1275. panel.Fit()
  1276. return panel
  1277. def _createVectorPage(self, parent):
  1278. """Create view settings page"""
  1279. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  1280. self.page['vector'] = {'id': 2,
  1281. 'notebook': self.foldpanelData.GetId()}
  1282. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1283. self.win['vector'] = {}
  1284. # selection
  1285. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1286. label=" %s " % (_("Vector map")))
  1287. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1288. vmaps = Select(parent=panel, type='vector',
  1289. onPopup=self.GselectOnPopup)
  1290. vmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetVector)
  1291. self.win['vector']['map'] = vmaps.GetId()
  1292. desc = wx.StaticText(parent=panel, id=wx.ID_ANY)
  1293. self.win['vector']['desc'] = desc.GetId()
  1294. boxSizer.Add(item=vmaps, proportion=0,
  1295. flag=wx.ALL,
  1296. border=3)
  1297. boxSizer.Add(item=desc, proportion=0,
  1298. flag=wx.ALL,
  1299. border=3)
  1300. pageSizer.Add(item=boxSizer, proportion=0,
  1301. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1302. border=3)
  1303. #
  1304. # vector lines
  1305. #
  1306. self.win['vector']['lines'] = {}
  1307. showLines = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1308. label=_("Show vector lines"))
  1309. showLines.SetValue(True)
  1310. self.win['vector']['lines']['show'] = showLines.GetId()
  1311. showLines.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
  1312. pageSizer.Add(item=showLines, proportion=0, flag=wx.LEFT |
  1313. wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
  1314. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1315. label=" %s " % (_("Vector lines")))
  1316. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1317. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  1318. # width
  1319. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1320. label=_("Line:")),
  1321. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1322. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1323. label=_("width:")),
  1324. pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL |
  1325. wx.ALIGN_RIGHT)
  1326. width = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1327. initial=1,
  1328. min=1,
  1329. max=100)
  1330. width.SetValue(1)
  1331. self.win['vector']['lines']['width'] = width.GetId()
  1332. width.Bind(wx.EVT_SPINCTRL, self.OnVectorLines)
  1333. gridSizer.Add(item=width, pos=(0, 2),
  1334. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  1335. # color
  1336. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1337. label=_("color:")),
  1338. pos=(0, 3), flag=wx.ALIGN_CENTER_VERTICAL |
  1339. wx.ALIGN_RIGHT)
  1340. color = csel.ColourSelect(panel, id=wx.ID_ANY,
  1341. colour=(0, 0, 0),
  1342. size=globalvar.DIALOG_COLOR_SIZE)
  1343. self.win['vector']['lines']['color'] = color.GetId()
  1344. color.Bind(csel.EVT_COLOURSELECT, self.OnVectorLines)
  1345. gridSizer.Add(item=color, pos=(0, 4), flag=wx.ALIGN_CENTER_VERTICAL |
  1346. wx.ALIGN_LEFT)
  1347. # thematic mapping
  1348. self.win['vector']['lines']['thematic'] = {}
  1349. checkThematicColor = wx.CheckBox(
  1350. parent=panel, id=wx.ID_ANY,
  1351. label=_("use color for thematic mapping"))
  1352. checkThematicWidth = wx.CheckBox(
  1353. parent=panel, id=wx.ID_ANY,
  1354. label=_("use width for thematic mapping"))
  1355. self.win['vector']['lines']['thematic'][
  1356. 'checkcolor'] = checkThematicColor.GetId()
  1357. self.win['vector']['lines']['thematic'][
  1358. 'checkwidth'] = checkThematicWidth.GetId()
  1359. checkThematicColor.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
  1360. checkThematicWidth.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
  1361. checkThematicColor.SetValue(False)
  1362. checkThematicWidth.SetValue(False)
  1363. vSizer = wx.BoxSizer(wx.VERTICAL)
  1364. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  1365. hSizer.Add(item=checkThematicColor, flag=wx.ALIGN_CENTER_VERTICAL,
  1366. border=5)
  1367. setThematic = wx.Button(parent=panel, id=wx.ID_ANY,
  1368. label=_("Set options..."))
  1369. self.win['vector']['lines']['thematic'][
  1370. 'buttoncolor'] = setThematic.GetId()
  1371. setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
  1372. hSizer.Add(item=wx.Size(-1, -1), proportion=1)
  1373. hSizer.Add(item=setThematic, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
  1374. border=5, proportion=0)
  1375. vSizer.Add(hSizer, flag=wx.EXPAND)
  1376. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  1377. hSizer.Add(item=checkThematicWidth, flag=wx.ALIGN_CENTER_VERTICAL,
  1378. border=5)
  1379. setThematic = wx.Button(parent=panel, id=wx.ID_ANY,
  1380. label=_("Set options..."))
  1381. self.win['vector']['lines']['thematic'][
  1382. 'buttonwidth'] = setThematic.GetId()
  1383. setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
  1384. hSizer.Add(item=wx.Size(-1, -1), proportion=1)
  1385. hSizer.Add(item=setThematic, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
  1386. border=5, proportion=0)
  1387. vSizer.Add(hSizer, flag=wx.EXPAND)
  1388. gridSizer.Add(item=vSizer, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1389. pos=(1, 1), span=(1, 5))
  1390. # display
  1391. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1392. label=_("Display")),
  1393. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL |
  1394. wx.ALIGN_LEFT)
  1395. display = wx.Choice(parent=panel, id=wx.ID_ANY, size=(-1, -1),
  1396. choices=[_("on surface(s):"),
  1397. _("as 3D")])
  1398. self.win['vector']['lines']['3d'] = display.GetId()
  1399. display.Bind(wx.EVT_CHOICE, self.OnVectorLinesMode)
  1400. gridSizer.Add(item=display, flag=wx.ALIGN_CENTER_VERTICAL |
  1401. wx.ALIGN_LEFT | wx.EXPAND, pos=(2, 1), span=(1, 4))
  1402. # height
  1403. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1404. label=_("Height above surface:")),
  1405. pos=(3, 5), flag=wx.ALIGN_BOTTOM | wx.EXPAND)
  1406. surface = wx.CheckListBox(parent=panel, id=wx.ID_ANY, size=(-1, 60),
  1407. choices=[], style=wx.LB_NEEDED_SB)
  1408. surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
  1409. self.win['vector']['lines']['surface'] = surface.GetId()
  1410. gridSizer.Add(item=surface,
  1411. pos=(3, 0), span=(3, 5),
  1412. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)
  1413. self._createControl(
  1414. panel,
  1415. data=self.win['vector']['lines'],
  1416. name='height',
  1417. size=-1,
  1418. range=(
  1419. 0,
  1420. 500),
  1421. sliderHor=True,
  1422. bind=(
  1423. self.OnVectorHeight,
  1424. self.OnVectorHeightFull,
  1425. self.OnVectorHeightText))
  1426. self.FindWindowById(self.win['vector']['lines'][
  1427. 'height']['slider']).SetValue(0)
  1428. self.FindWindowById(self.win['vector']['lines'][
  1429. 'height']['text']).SetValue(0)
  1430. gridSizer.Add(
  1431. item=self.FindWindowById(
  1432. self.win['vector']['lines']['height']['slider']), pos=(
  1433. 4, 5), flag=wx.EXPAND | wx.ALIGN_RIGHT)
  1434. gridSizer.Add(
  1435. item=self.FindWindowById(
  1436. self.win['vector']['lines']['height']['text']), pos=(
  1437. 5, 5), flag=wx.ALIGN_CENTER)
  1438. gridSizer.AddGrowableCol(5)
  1439. boxSizer.Add(item=gridSizer, proportion=1,
  1440. flag=wx.ALL | wx.EXPAND, border=3)
  1441. pageSizer.Add(item=boxSizer, proportion=0,
  1442. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1443. border=3)
  1444. #
  1445. # vector points
  1446. #
  1447. self.win['vector']['points'] = {}
  1448. showPoints = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1449. label=_("Show vector points"))
  1450. showPoints.SetValue(True)
  1451. self.win['vector']['points']['show'] = showPoints.GetId()
  1452. showPoints.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
  1453. pageSizer.Add(item=showPoints, proportion=0, flag=wx.LEFT |
  1454. wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
  1455. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1456. label=" %s " % (_("Vector points")))
  1457. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1458. vertSizer = wx.BoxSizer(wx.VERTICAL)
  1459. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  1460. # icon size
  1461. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1462. label=_("Icon:")),
  1463. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1464. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1465. label=_("size:")),
  1466. pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL |
  1467. wx.ALIGN_RIGHT)
  1468. if fs:
  1469. isize = fs.FloatSpin(parent=panel, id=wx.ID_ANY,
  1470. min_val=0, max_val=1e6,
  1471. increment=1, value=1, style=fs.FS_RIGHT)
  1472. isize.SetFormat("%f")
  1473. isize.SetDigits(1)
  1474. isize.Bind(fs.EVT_FLOATSPIN, self.OnVectorPoints)
  1475. else:
  1476. isize = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1477. initial=1,
  1478. min=1,
  1479. max=1e6)
  1480. isize.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
  1481. isize.SetName('value')
  1482. isize.SetValue(100)
  1483. self.win['vector']['points']['size'] = isize.GetId()
  1484. gridSizer.Add(item=isize, pos=(0, 2),
  1485. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  1486. # icon color
  1487. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1488. label=_("color:")),
  1489. pos=(0, 3), flag=wx.ALIGN_CENTER_VERTICAL |
  1490. wx.ALIGN_RIGHT)
  1491. icolor = csel.ColourSelect(panel, id=wx.ID_ANY,
  1492. size=globalvar.DIALOG_COLOR_SIZE)
  1493. icolor.SetName("color")
  1494. icolor.SetColour((0, 0, 255))
  1495. self.win['vector']['points']['color'] = icolor.GetId()
  1496. icolor.Bind(csel.EVT_COLOURSELECT, self.OnVectorPoints)
  1497. gridSizer.Add(item=icolor, flag=wx.ALIGN_CENTER_VERTICAL |
  1498. wx.ALIGN_LEFT,
  1499. pos=(0, 4))
  1500. # icon width - seems to do nothing
  1501. # gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1502. # label = _("width")),
  1503. # pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL |
  1504. # wx.ALIGN_RIGHT)
  1505. ##
  1506. # iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  1507. ## initial = 1,
  1508. ## min = 1,
  1509. # max = 1e6)
  1510. # iwidth.SetName('value')
  1511. # iwidth.SetValue(100)
  1512. ## self.win['vector']['points']['width'] = iwidth.GetId()
  1513. ## iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
  1514. ## iwidth.Bind(wx.EVT_TEXT, self.OnVectorPoints)
  1515. # gridSizer.Add(item = iwidth, pos = (1, 2),
  1516. # flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  1517. # icon symbol
  1518. gridSizer.Add(
  1519. item=wx.StaticText(
  1520. parent=panel, id=wx.ID_ANY, label=_("symbol:")), pos=(
  1521. 0, 5), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
  1522. isym = wx.Choice(
  1523. parent=panel, id=wx.ID_ANY, size=(100, -1),
  1524. choices=UserSettings.Get(
  1525. group='nviz', key='vector', subkey=['points', 'marker'],
  1526. settings_type='internal'))
  1527. isym.SetName("selection")
  1528. self.win['vector']['points']['marker'] = isym.GetId()
  1529. isym.Bind(wx.EVT_CHOICE, self.OnVectorPoints)
  1530. gridSizer.Add(item=isym, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  1531. pos=(0, 6))
  1532. # thematic mapping
  1533. self.win['vector']['points']['thematic'] = {}
  1534. checkThematicColor = wx.CheckBox(
  1535. parent=panel, id=wx.ID_ANY,
  1536. label=_("use color for thematic mapping"))
  1537. checkThematicSize = wx.CheckBox(
  1538. parent=panel, id=wx.ID_ANY,
  1539. label=_("use size for thematic mapping"))
  1540. self.win['vector']['points']['thematic'][
  1541. 'checkcolor'] = checkThematicColor.GetId()
  1542. self.win['vector']['points']['thematic'][
  1543. 'checksize'] = checkThematicSize.GetId()
  1544. checkThematicColor.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
  1545. checkThematicSize.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
  1546. checkThematicColor.SetValue(False)
  1547. checkThematicSize.SetValue(False)
  1548. gridSizer.Add(
  1549. item=checkThematicColor,
  1550. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  1551. pos=(
  1552. 1,
  1553. 1),
  1554. span=(
  1555. 1,
  1556. 5))
  1557. setThematic = wx.Button(parent=panel, id=wx.ID_ANY,
  1558. label=_("Set options..."))
  1559. self.win['vector']['points']['thematic'][
  1560. 'buttoncolor'] = setThematic.GetId()
  1561. setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
  1562. gridSizer.Add(item=setThematic, flag=wx.ALIGN_CENTER_VERTICAL,
  1563. pos=(1, 6))
  1564. gridSizer.Add(
  1565. item=checkThematicSize,
  1566. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  1567. pos=(
  1568. 2,
  1569. 1),
  1570. span=(
  1571. 1,
  1572. 5))
  1573. setThematic = wx.Button(parent=panel, id=wx.ID_ANY,
  1574. label=_("Set options..."))
  1575. self.win['vector']['points']['thematic'][
  1576. 'buttonsize'] = setThematic.GetId()
  1577. setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
  1578. gridSizer.Add(item=setThematic, flag=wx.ALIGN_CENTER_VERTICAL,
  1579. pos=(2, 6))
  1580. gridSizer.AddGrowableCol(0)
  1581. gridSizer.AddGrowableCol(2)
  1582. gridSizer.AddGrowableCol(4)
  1583. gridSizer.AddGrowableCol(6)
  1584. vertSizer.Add(gridSizer, proportion=0, flag=wx.EXPAND, border=0)
  1585. # high
  1586. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  1587. gridSizer.Add(
  1588. item=wx.StaticText(
  1589. parent=panel, label=_("Display")), pos=(
  1590. 0, 0), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  1591. display = wx.Choice(parent=panel)
  1592. self.win['vector']['points']['3d'] = display.GetId()
  1593. display.Bind(wx.EVT_CHOICE, self.OnVectorPointsMode)
  1594. gridSizer.Add(item=display,
  1595. pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)
  1596. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1597. label=_("Height above surface:")),
  1598. pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1599. surface = wx.CheckListBox(parent=panel, id=wx.ID_ANY, size=(-1, 60),
  1600. choices=[], style=wx.LB_NEEDED_SB)
  1601. surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
  1602. self.win['vector']['points']['surface'] = surface.GetId()
  1603. gridSizer.Add(item=surface,
  1604. pos=(1, 0), span=(3, 2),
  1605. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)
  1606. self._createControl(
  1607. panel,
  1608. data=self.win['vector']['points'],
  1609. name='height',
  1610. size=-1,
  1611. range=(
  1612. 0,
  1613. 500),
  1614. bind=(
  1615. self.OnVectorHeight,
  1616. self.OnVectorHeightFull,
  1617. self.OnVectorHeightText))
  1618. self.FindWindowById(self.win['vector']['points'][
  1619. 'height']['slider']).SetValue(0)
  1620. self.FindWindowById(self.win['vector']['points'][
  1621. 'height']['text']).SetValue(0)
  1622. gridSizer.Add(
  1623. item=self.FindWindowById(
  1624. self.win['vector']['points']['height']['slider']), pos=(
  1625. 2, 2), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
  1626. gridSizer.Add(
  1627. item=self.FindWindowById(
  1628. self.win['vector']['points']['height']['text']), pos=(
  1629. 3, 2), flag=wx.ALIGN_CENTER)
  1630. gridSizer.AddGrowableCol(2)
  1631. vertSizer.Add(gridSizer, proportion=0, flag=wx.EXPAND, border=0)
  1632. boxSizer.Add(item=vertSizer, proportion=1,
  1633. flag=wx.ALL | wx.EXPAND, border=3)
  1634. pageSizer.Add(item=boxSizer, proportion=0,
  1635. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1636. border=3)
  1637. panel.SetSizer(pageSizer)
  1638. panel.Fit()
  1639. return panel
  1640. def GselectOnPopup(self, ltype, exclude=False):
  1641. """Update gselect.Select() items"""
  1642. maps = list()
  1643. for layer in self.mapWindow.Map.GetListOfLayers(
  1644. ltype=ltype, active=True):
  1645. maps.append(layer.GetName())
  1646. return maps, exclude
  1647. def _createVolumePage(self, parent):
  1648. """Create view settings page"""
  1649. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  1650. self.page['volume'] = {'id': 3,
  1651. 'notebook': self.foldpanelData.GetId()}
  1652. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1653. self.win['volume'] = {}
  1654. # selection
  1655. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1656. label=" %s " % (_("3D raster map")))
  1657. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1658. rmaps = Select(parent=panel, type='raster_3d',
  1659. onPopup=self.GselectOnPopup)
  1660. rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetRaster3D)
  1661. self.win['volume']['map'] = rmaps.GetId()
  1662. desc = wx.StaticText(parent=panel, id=wx.ID_ANY)
  1663. self.win['volume']['desc'] = desc.GetId()
  1664. boxSizer.Add(item=rmaps, proportion=0,
  1665. flag=wx.ALL,
  1666. border=3)
  1667. boxSizer.Add(item=desc, proportion=0,
  1668. flag=wx.ALL,
  1669. border=3)
  1670. pageSizer.Add(item=boxSizer, proportion=0,
  1671. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1672. border=3)
  1673. #
  1674. # draw
  1675. #
  1676. self.win['volume']['draw'] = {}
  1677. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1678. label=" %s " % (_("Draw")))
  1679. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1680. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  1681. # gridSizer.AddGrowableCol(4)
  1682. # mode
  1683. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1684. label=_("Mode:")),
  1685. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1686. mode = wx.Choice(parent=panel, id=wx.ID_ANY, size=(-1, -1),
  1687. choices=[_("isosurfaces"),
  1688. _("slices")])
  1689. mode.SetSelection(0)
  1690. mode.SetName("selection")
  1691. mode.Bind(wx.EVT_CHOICE, self.OnVolumeMode)
  1692. self.win['volume']['draw']['mode'] = mode.GetId()
  1693. gridSizer.Add(item=mode, flag=wx.ALIGN_CENTER_VERTICAL,
  1694. pos=(0, 1))
  1695. # shading
  1696. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1697. label=_("Shading:")),
  1698. pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1699. shade = wx.Choice(parent=panel, id=wx.ID_ANY, size=(100, -1),
  1700. choices=[_("flat"),
  1701. _("gouraud")])
  1702. shade.SetName("selection")
  1703. self.win['volume']['draw']['shading'] = shade.GetId()
  1704. shade.Bind(wx.EVT_CHOICE, self.OnVolumeDrawMode)
  1705. gridSizer.Add(item=shade, flag=wx.ALIGN_CENTER_VERTICAL,
  1706. pos=(0, 3))
  1707. # resolution (mode)
  1708. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1709. label=_("Resolution:")),
  1710. pos=(0, 4), flag=wx.ALIGN_CENTER_VERTICAL)
  1711. resol = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1712. initial=1,
  1713. min=1,
  1714. max=100)
  1715. resol.SetName("value")
  1716. self.win['volume']['draw']['resolution'] = resol.GetId()
  1717. resol.Bind(wx.EVT_SPINCTRL, self.OnVolumeResolution)
  1718. resol.Bind(wx.EVT_TEXT, self.OnVolumeResolution)
  1719. gridSizer.Add(item=resol, pos=(0, 5))
  1720. # draw wire box
  1721. box = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1722. label=_("Draw wire box"))
  1723. box.SetName("value")
  1724. self.win['volume']['draw']['box'] = box.GetId()
  1725. box.Bind(wx.EVT_CHECKBOX, self.OnVolumeDrawBox)
  1726. gridSizer.Add(item=box, pos=(1, 0), span=(1, 6))
  1727. boxSizer.Add(item=gridSizer, proportion=0,
  1728. flag=wx.ALL | wx.EXPAND, border=3)
  1729. pageSizer.Add(item=boxSizer, proportion=0,
  1730. flag=wx.EXPAND | wx.ALL,
  1731. border=3)
  1732. #
  1733. # manage isosurfaces
  1734. #
  1735. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1736. label=" %s " % (_("List of isosurfaces")))
  1737. box.SetName('listStaticBox')
  1738. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1739. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1740. # list
  1741. isolevel = wx.CheckListBox(parent=panel, id=wx.ID_ANY,
  1742. size=(300, 150))
  1743. self.Bind(wx.EVT_CHECKLISTBOX, self.OnVolumeCheck, isolevel)
  1744. self.Bind(wx.EVT_LISTBOX, self.OnVolumeSelect, isolevel)
  1745. self.win['volume']['isosurfs'] = isolevel.GetId()
  1746. self.win['volume']['slices'] = isolevel.GetId()
  1747. gridSizer.Add(item=isolevel, pos=(0, 0), span=(4, 1))
  1748. # buttons (add, delete, move up, move down)
  1749. btnAdd = wx.Button(parent=panel, id=wx.ID_ADD)
  1750. self.win['volume']['btnAdd'] = btnAdd.GetId()
  1751. btnAdd.Bind(wx.EVT_BUTTON, self.OnVolumeAdd)
  1752. gridSizer.Add(item=btnAdd,
  1753. pos=(0, 1))
  1754. btnDelete = wx.Button(parent=panel, id=wx.ID_DELETE)
  1755. self.win['volume']['btnDelete'] = btnDelete.GetId()
  1756. btnDelete.Bind(wx.EVT_BUTTON, self.OnVolumeDelete)
  1757. btnDelete.Enable(False)
  1758. gridSizer.Add(item=btnDelete,
  1759. pos=(1, 1))
  1760. btnMoveUp = wx.Button(parent=panel, id=wx.ID_UP)
  1761. self.win['volume']['btnMoveUp'] = btnMoveUp.GetId()
  1762. btnMoveUp.Bind(wx.EVT_BUTTON, self.OnVolumeMoveUp)
  1763. btnMoveUp.Enable(False)
  1764. gridSizer.Add(item=btnMoveUp,
  1765. pos=(2, 1))
  1766. btnMoveDown = wx.Button(parent=panel, id=wx.ID_DOWN)
  1767. self.win['volume']['btnMoveDown'] = btnMoveDown.GetId()
  1768. btnMoveDown.Bind(wx.EVT_BUTTON, self.OnVolumeMoveDown)
  1769. btnMoveDown.Enable(False)
  1770. gridSizer.Add(item=btnMoveDown,
  1771. pos=(3, 1))
  1772. boxSizer.Add(item=gridSizer, proportion=1,
  1773. flag=wx.ALL | wx.EXPAND, border=3)
  1774. pageSizer.Add(item=boxSizer, proportion=0,
  1775. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1776. border=3)
  1777. # isosurface/slice
  1778. sizer = wx.BoxSizer()
  1779. self.isoPanel = self._createIsosurfacePanel(panel)
  1780. self.slicePanel = self._createSlicePanel(panel)
  1781. sizer.Add(
  1782. self.isoPanel,
  1783. proportion=1,
  1784. flag=wx.EXPAND | wx.ALL,
  1785. border=0)
  1786. sizer.Add(
  1787. self.slicePanel,
  1788. proportion=1,
  1789. flag=wx.EXPAND | wx.ALL,
  1790. border=0)
  1791. sizer.Hide(self.slicePanel)
  1792. pageSizer.Add(item=sizer, proportion=0,
  1793. flag=wx.EXPAND | wx.ALL,
  1794. border=3)
  1795. #
  1796. # position
  1797. #
  1798. self.win['volume']['position'] = {}
  1799. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1800. label=" %s " % (_("Position")))
  1801. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1802. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1803. # position
  1804. self._createControl(panel,
  1805. data=self.win['volume'],
  1806. name='position',
  1807. range=(-10000,
  1808. 10000),
  1809. floatSlider=True,
  1810. bind=(self.OnVolumePosition,
  1811. self.OnVolumePositionChanged,
  1812. self.OnVolumePositionText))
  1813. axis = wx.Choice(parent=panel, id=wx.ID_ANY, size=(75, -1),
  1814. choices=["X",
  1815. "Y",
  1816. "Z"])
  1817. reset = wx.Button(panel, id=wx.ID_ANY, label=_("Reset"))
  1818. reset.SetToolTipString(_("Reset to default position"))
  1819. reset.Bind(wx.EVT_BUTTON, self.OnResetVolumePosition)
  1820. self.win['volume']['position']['reset'] = reset.GetId()
  1821. self.win['volume']['position']['axis'] = axis.GetId()
  1822. axis.SetSelection(2) # Z
  1823. axis.Bind(wx.EVT_CHOICE, self.OnVolumeAxis)
  1824. pslide = self.FindWindowById(self.win['volume']['position']['slider'])
  1825. ptext = self.FindWindowById(self.win['volume']['position']['text'])
  1826. ptext.SetValue('0')
  1827. gridSizer.Add(item=axis, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
  1828. gridSizer.Add(item=pslide, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 1))
  1829. gridSizer.Add(item=ptext, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 2))
  1830. gridSizer.Add(
  1831. item=reset,
  1832. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  1833. pos=(
  1834. 0,
  1835. 3))
  1836. gridSizer.AddGrowableCol(3)
  1837. boxSizer.Add(item=gridSizer, proportion=1,
  1838. flag=wx.ALL | wx.EXPAND, border=3)
  1839. pageSizer.Add(item=boxSizer, proportion=0,
  1840. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1841. border=3)
  1842. panel.SetSizer(pageSizer)
  1843. panel.Fit()
  1844. return panel
  1845. def _createLightPage(self, parent):
  1846. """Create light page"""
  1847. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  1848. self.page['light'] = {'id': 0,
  1849. 'notebook': self.foldpanelAppear.GetId()}
  1850. self.win['light'] = {}
  1851. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1852. show = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1853. label=_("Show light model"))
  1854. show.Bind(wx.EVT_CHECKBOX, self.OnShowLightModel)
  1855. show.SetValue(True)
  1856. self._display.showLight = True
  1857. pageSizer.Add(item=show, proportion=0,
  1858. flag=wx.ALL, border=3)
  1859. # surface = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1860. # label = _("Follow source viewpoint"))
  1861. # pageSizer.Add(item = surface, proportion = 0,
  1862. # flag = wx.ALL, border = 3)
  1863. # position
  1864. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1865. label=" %s " % (_("Light source position")))
  1866. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1867. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1868. posSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1869. self._createCompass(panel=panel, sizer=posSizer, type='light')
  1870. pos = LightPositionWindow(panel, id=wx.ID_ANY, size=(175, 175),
  1871. mapwindow=self.mapWindow)
  1872. self.win['light']['position'] = pos.GetId()
  1873. posSizer.Add(
  1874. item=pos, pos=(1, 1),
  1875. flag=wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
  1876. gridSizer.Add(item=posSizer, pos=(0, 0))
  1877. # height
  1878. tooltip = _("Adjusts the light height")
  1879. self._createControl(
  1880. panel, data=self.win['light'], name='z', sliderHor=False, range=(
  1881. 0, 100), tooltip=tooltip, bind=(
  1882. self.OnLightChange, self.OnLightChanged, self.OnLightChange))
  1883. heightSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1884. heightSizer.Add(
  1885. item=wx.StaticText(
  1886. panel, id=wx.ID_ANY, label=_("Height:")), pos=(
  1887. 0, 0), flag=wx.ALIGN_LEFT, span=(
  1888. 1, 2))
  1889. heightSizer.Add(
  1890. item=self.FindWindowById(
  1891. self.win['light']['z']['slider']), flag=wx.ALIGN_RIGHT, pos=(
  1892. 1, 0))
  1893. heightSizer.Add(item=self.FindWindowById(
  1894. self.win['light']['z']['text']),
  1895. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
  1896. wx.BOTTOM | wx.RIGHT, pos=(1, 1))
  1897. gridSizer.Add(item=heightSizer, pos=(0, 2), flag=wx.ALIGN_RIGHT)
  1898. boxSizer.Add(item=gridSizer, proportion=1,
  1899. flag=wx.ALL | wx.EXPAND, border=2)
  1900. pageSizer.Add(item=boxSizer, proportion=0,
  1901. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1902. border=3)
  1903. # position
  1904. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1905. label=" %s " % (_("Light color and intensity")))
  1906. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1907. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1908. gridSizer.Add(
  1909. item=wx.StaticText(
  1910. panel, id=wx.ID_ANY, label=_("Color:")), pos=(
  1911. 0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1912. color = csel.ColourSelect(
  1913. panel, id=wx.ID_ANY, colour=UserSettings.Get(
  1914. group='nviz', key='light', subkey='color'),
  1915. size=globalvar.DIALOG_COLOR_SIZE)
  1916. self.win['light']['color'] = color.GetId()
  1917. color.Bind(csel.EVT_COLOURSELECT, self.OnLightColor)
  1918. gridSizer.Add(item=color, pos=(0, 2))
  1919. gridSizer.Add(
  1920. item=wx.StaticText(
  1921. panel, id=wx.ID_ANY, label=_("Brightness:")), pos=(
  1922. 1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1923. tooltip = _("Adjusts the brightness of the light")
  1924. self._createControl(
  1925. panel, data=self.win['light'], name='bright', size=300, range=(
  1926. 0, 100), tooltip=tooltip, bind=(
  1927. self.OnLightValue, self.OnLightChanged, self.OnLightValue))
  1928. gridSizer.Add(
  1929. item=self.FindWindowById(
  1930. self.win['light']['bright']['slider']), pos=(
  1931. 1, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  1932. gridSizer.Add(
  1933. item=self.FindWindowById(
  1934. self.win['light']['bright']['text']), pos=(
  1935. 1, 2), flag=wx.ALIGN_CENTER)
  1936. gridSizer.Add(
  1937. item=wx.StaticText(
  1938. panel, id=wx.ID_ANY, label=_("Ambient:")), pos=(
  1939. 2, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1940. tooltip = _("Adjusts the ambient light")
  1941. self._createControl(
  1942. panel, data=self.win['light'], name='ambient', size=300, range=(
  1943. 0, 100), tooltip=tooltip, bind=(
  1944. self.OnLightValue, self.OnLightChanged, self.OnLightValue))
  1945. gridSizer.Add(
  1946. item=self.FindWindowById(
  1947. self.win['light']['ambient']['slider']), pos=(
  1948. 2, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  1949. gridSizer.Add(
  1950. item=self.FindWindowById(
  1951. self.win['light']['ambient']['text']), pos=(
  1952. 2, 2), flag=wx.ALIGN_CENTER)
  1953. boxSizer.Add(item=gridSizer, proportion=1,
  1954. flag=wx.ALL | wx.EXPAND, border=2)
  1955. pageSizer.Add(item=boxSizer, proportion=0,
  1956. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1957. border=3)
  1958. # reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
  1959. # reset.SetToolTipString(_("Reset to default view"))
  1960. # # self.win['reset'] = reset.GetId()
  1961. # reset.Bind(wx.EVT_BUTTON, self.OnResetView)
  1962. # viewSizer.Add(item = reset, proportion = 1,
  1963. # flag = wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT,
  1964. # border = 5)
  1965. # gridSizer.AddGrowableCol(3)
  1966. # gridSizer.Add(item = viewSizer, pos = (4, 0), span = (1, 2),
  1967. # flag = wx.EXPAND)
  1968. panel.SetSizer(pageSizer)
  1969. panel.Layout()
  1970. panel.Fit()
  1971. return panel
  1972. def _createFringePage(self, parent):
  1973. """Create fringe page"""
  1974. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  1975. self.page['fringe'] = {'id': 1,
  1976. 'notebook': self.foldpanelAppear.GetId()}
  1977. self.win['fringe'] = {}
  1978. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1979. # selection
  1980. rbox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1981. label=" %s " % (_("Surface")))
  1982. rboxSizer = wx.StaticBoxSizer(rbox, wx.VERTICAL)
  1983. rmaps = Select(parent=panel, type='raster',
  1984. onPopup=self.GselectOnPopup)
  1985. rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetSurface)
  1986. self.win['fringe']['map'] = rmaps.GetId()
  1987. rboxSizer.Add(item=rmaps, proportion=0,
  1988. flag=wx.ALL,
  1989. border=3)
  1990. pageSizer.Add(item=rboxSizer, proportion=0,
  1991. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1992. border=3)
  1993. ebox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1994. label=" %s " % (_("Edges with fringe")))
  1995. eboxSizer = wx.StaticBoxSizer(ebox, wx.HORIZONTAL)
  1996. for edge in [(_("N && W"), "nw"),
  1997. (_("N && E"), "ne"),
  1998. (_("S && W"), "sw"),
  1999. (_("S && E"), "se")]:
  2000. chkbox = wx.CheckBox(parent=panel,
  2001. label=edge[0],
  2002. name=edge[1])
  2003. self.win['fringe'][edge[1]] = chkbox.GetId()
  2004. eboxSizer.Add(
  2005. item=chkbox,
  2006. proportion=0,
  2007. flag=wx.ADJUST_MINSIZE | wx.LEFT | wx.RIGHT,
  2008. border=5)
  2009. chkbox.Bind(wx.EVT_CHECKBOX, self.OnFringe)
  2010. pageSizer.Add(item=eboxSizer, proportion=0,
  2011. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  2012. border=3)
  2013. sbox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  2014. label=" %s " % (_("Settings")))
  2015. sboxSizer = wx.StaticBoxSizer(sbox, wx.HORIZONTAL)
  2016. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  2017. # elevation
  2018. gridSizer.Add(
  2019. item=wx.StaticText(
  2020. parent=panel, id=wx.ID_ANY,
  2021. label=_("Elevation of fringe from bottom:")),
  2022. pos=(0, 0),
  2023. flag=wx.ALIGN_CENTER_VERTICAL)
  2024. spin = wx.SpinCtrl(parent=panel, id=wx.ID_ANY,
  2025. size=(65, -1), min=-1e6, max=1e6)
  2026. spin.SetValue(
  2027. UserSettings.Get(
  2028. group='nviz',
  2029. key='fringe',
  2030. subkey='elev'))
  2031. spin.Bind(wx.EVT_SPINCTRL, self.OnFringe)
  2032. self.win['fringe']['elev'] = spin.GetId()
  2033. gridSizer.Add(item=spin, pos=(0, 1))
  2034. # color
  2035. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  2036. label=_("Color:")),
  2037. pos=(1, 0),
  2038. flag=wx.ALIGN_CENTER_VERTICAL)
  2039. color = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  2040. size=globalvar.DIALOG_COLOR_SIZE)
  2041. color.SetColour(UserSettings.Get(group='nviz', key='fringe',
  2042. subkey='color'))
  2043. color.Bind(csel.EVT_COLOURSELECT, self.OnFringe)
  2044. self.win['fringe']['color'] = color.GetId()
  2045. gridSizer.Add(item=color, pos=(1, 1))
  2046. sboxSizer.Add(item=gridSizer, proportion=1,
  2047. flag=wx.ALL | wx.EXPAND, border=3)
  2048. pageSizer.Add(item=sboxSizer, proportion=0,
  2049. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  2050. border=3)
  2051. panel.SetSizer(pageSizer)
  2052. panel.Layout()
  2053. panel.Fit()
  2054. return panel
  2055. def _createDecorationPage(self, parent):
  2056. """Create decoration (north arrow, scalebar, legend) page"""
  2057. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  2058. self.page['decoration'] = {'id': 2,
  2059. 'notebook': self.foldpanelAppear.GetId()}
  2060. self.win['decoration'] = {}
  2061. pageSizer = wx.BoxSizer(wx.VERTICAL)
  2062. # north arrow
  2063. self.win['decoration']['arrow'] = {}
  2064. nabox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  2065. label=" %s " % (_("North Arrow")))
  2066. naboxSizer = wx.StaticBoxSizer(nabox, wx.VERTICAL)
  2067. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  2068. # size
  2069. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  2070. label=_("Arrow length (in map units):")),
  2071. pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  2072. sizeCtrl = NumTextCtrl(
  2073. parent=panel, id=wx.ID_ANY, size=(
  2074. 65, -1), style=wx.TE_PROCESS_ENTER)
  2075. gridSizer.Add(sizeCtrl, pos=(0, 2))
  2076. self.win['decoration']['arrow']['size'] = sizeCtrl.GetId()
  2077. sizeCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnDecorationProp)
  2078. sizeCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnDecorationProp)
  2079. # color
  2080. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  2081. label=_("Arrow color:")),
  2082. pos=(1, 0), span=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  2083. color = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  2084. size=globalvar.DIALOG_COLOR_SIZE)
  2085. gridSizer.Add(color, pos=(1, 2))
  2086. self.win['decoration']['arrow']['color'] = color.GetId()
  2087. color.Bind(csel.EVT_COLOURSELECT, self.OnDecorationProp)
  2088. # control
  2089. toggle = wx.ToggleButton(
  2090. parent=panel,
  2091. id=wx.ID_ANY,
  2092. label=_("Place arrow"))
  2093. gridSizer.Add(item=toggle, pos=(2, 0))
  2094. toggle.Bind(wx.EVT_TOGGLEBUTTON, self.OnDecorationPlacement)
  2095. self.win['decoration']['arrow']['place'] = toggle.GetId()
  2096. toggle.SetName('placeArrow')
  2097. delete = wx.Button(parent=panel, id=wx.ID_ANY, label=_("Delete"))
  2098. self.win['decoration']['arrow']['delete'] = delete.GetId()
  2099. gridSizer.Add(item=delete, pos=(2, 1))
  2100. delete.Bind(wx.EVT_BUTTON, self.OnArrowDelete)
  2101. shown = self.mapWindow.decoration['arrow']['show']
  2102. delete.Enable(shown)
  2103. naboxSizer.Add(item=gridSizer, proportion=0, flag=wx.EXPAND, border=3)
  2104. pageSizer.Add(item=naboxSizer, proportion=0,
  2105. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  2106. border=3)
  2107. # scale bars
  2108. self.win['decoration']['scalebar'] = {}
  2109. nabox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  2110. label=" %s " % (_("Scale bar")))
  2111. naboxSizer = wx.StaticBoxSizer(nabox, wx.VERTICAL)
  2112. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  2113. # size
  2114. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  2115. label=_("Scale bar length (in map units):")),
  2116. pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  2117. sizeCtrl = NumTextCtrl(
  2118. parent=panel, id=wx.ID_ANY, size=(
  2119. 65, -1), style=wx.TE_PROCESS_ENTER)
  2120. gridSizer.Add(sizeCtrl, pos=(0, 2))
  2121. self.win['decoration']['scalebar']['size'] = sizeCtrl.GetId()
  2122. sizeCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnDecorationProp)
  2123. sizeCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnDecorationProp)
  2124. # color
  2125. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  2126. label=_("Scale bar color:")),
  2127. pos=(1, 0), span=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  2128. color = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  2129. size=globalvar.DIALOG_COLOR_SIZE)
  2130. gridSizer.Add(color, pos=(1, 2))
  2131. self.win['decoration']['scalebar']['color'] = color.GetId()
  2132. color.Bind(csel.EVT_COLOURSELECT, self.OnDecorationProp)
  2133. # control
  2134. toggle = wx.ToggleButton(
  2135. parent=panel,
  2136. id=wx.ID_ANY,
  2137. label=_("Place new scale bar"))
  2138. gridSizer.Add(item=toggle, pos=(2, 0))
  2139. toggle.Bind(wx.EVT_TOGGLEBUTTON, self.OnDecorationPlacement)
  2140. self.win['decoration']['scalebar']['place'] = toggle.GetId()
  2141. toggle.SetName('placeScalebar')
  2142. scalebarChoice = wx.Choice(parent=panel, id=wx.ID_ANY, choices=[])
  2143. self.win['decoration']['scalebar']['choice'] = scalebarChoice.GetId()
  2144. gridSizer.Add(item=scalebarChoice, pos=(3, 0), flag=wx.EXPAND)
  2145. delete = wx.Button(parent=panel, id=wx.ID_ANY, label=_("Delete"))
  2146. self.win['decoration']['scalebar']['delete'] = delete.GetId()
  2147. gridSizer.Add(item=delete, pos=(3, 1))
  2148. delete.Bind(wx.EVT_BUTTON, self.OnScalebarDelete)
  2149. naboxSizer.Add(item=gridSizer, proportion=0, flag=wx.EXPAND, border=3)
  2150. pageSizer.Add(item=naboxSizer, proportion=0,
  2151. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  2152. border=3)
  2153. self.DisableScalebarControls()
  2154. panel.SetSizer(pageSizer)
  2155. panel.Layout()
  2156. panel.Fit()
  2157. return panel
  2158. def GetLayerData(self, nvizType, nameOnly=False):
  2159. """Get nviz data"""
  2160. name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
  2161. if nameOnly:
  2162. return name
  2163. if nvizType == 'surface' or nvizType == 'fringe':
  2164. return self._getLayerPropertiesByName(name, mapType='raster')
  2165. elif nvizType == 'vector':
  2166. return self._getLayerPropertiesByName(name, mapType='vector')
  2167. elif nvizType == 'volume':
  2168. return self._getLayerPropertiesByName(name, mapType='raster_3d')
  2169. return None
  2170. def _getMapLayerByName(self, name, mapType):
  2171. """Get layer (render.Layer) by name and type.
  2172. :param name: layer name
  2173. :param mapType: map type (raster, vector, raster_3d)
  2174. """
  2175. layers = self.mapWindow.Map.GetListOfLayers(ltype=mapType, name=name)
  2176. if layers:
  2177. return layers[0]
  2178. return None
  2179. def _getLayerPropertiesByName(self, name, mapType):
  2180. """Get nviz properties stored in layertree items by name and type.
  2181. :param name: layer name
  2182. :param mapType: map type (raster, vector, raster_3d)
  2183. """
  2184. items = self.tree.FindItemByData(key='name', value=name)
  2185. if not items:
  2186. return None
  2187. for item in items:
  2188. if self.tree.GetLayerInfo(item, key='type') == mapType:
  2189. return self.tree.GetLayerInfo(item, key='nviz')
  2190. return None
  2191. def OnRecord(self, event):
  2192. """Animation: start recording"""
  2193. anim = self.mapWindow.GetAnimation()
  2194. if not anim.IsPaused():
  2195. if anim.Exists() and not anim.IsSaved():
  2196. msg = _(
  2197. "Do you want to record new animation without saving the previous one?")
  2198. dlg = wx.MessageDialog(parent=self,
  2199. message=msg,
  2200. caption=_("Animation already axists"),
  2201. style=wx.YES_NO | wx.CENTRE)
  2202. if dlg.ShowModal() == wx.ID_NO:
  2203. dlg.Destroy()
  2204. return
  2205. anim.Clear()
  2206. self.UpdateFrameIndex(0)
  2207. self.UpdateFrameCount()
  2208. anim.SetPause(False)
  2209. anim.SetMode(mode='record')
  2210. anim.Start()
  2211. self.FindWindowById(self.win['anim']['play']).Disable()
  2212. self.FindWindowById(self.win['anim']['record']).Disable()
  2213. self.FindWindowById(self.win['anim']['pause']).Enable()
  2214. self.FindWindowById(self.win['anim']['stop']).Enable()
  2215. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  2216. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  2217. def OnPlay(self, event):
  2218. """Animation: replay"""
  2219. anim = self.mapWindow.GetAnimation()
  2220. anim.SetPause(False)
  2221. anim.SetMode(mode='play')
  2222. anim.Start()
  2223. self.FindWindowById(self.win['anim']['play']).Disable()
  2224. self.FindWindowById(self.win['anim']['record']).Disable()
  2225. self.FindWindowById(self.win['anim']['pause']).Enable()
  2226. self.FindWindowById(self.win['anim']['stop']).Enable()
  2227. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Enable()
  2228. self.FindWindowById(self.win['anim']['frameIndex']['text']).Enable()
  2229. def OnStop(self, event):
  2230. """Animation: stop recording/replaying"""
  2231. anim = self.mapWindow.GetAnimation()
  2232. anim.SetPause(False)
  2233. if anim.GetMode() == 'save':
  2234. anim.StopSaving()
  2235. if anim.IsRunning():
  2236. anim.Stop()
  2237. self.UpdateFrameIndex(0)
  2238. self.FindWindowById(self.win['anim']['play']).Enable()
  2239. self.FindWindowById(self.win['anim']['record']).Enable()
  2240. self.FindWindowById(self.win['anim']['pause']).Disable()
  2241. self.FindWindowById(self.win['anim']['stop']).Disable()
  2242. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  2243. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  2244. def OnPause(self, event):
  2245. """Pause animation"""
  2246. anim = self.mapWindow.GetAnimation()
  2247. anim.SetPause(True)
  2248. mode = anim.GetMode()
  2249. if anim.IsRunning():
  2250. anim.Pause()
  2251. if mode == "record":
  2252. self.FindWindowById(self.win['anim']['play']).Disable()
  2253. self.FindWindowById(self.win['anim']['record']).Enable()
  2254. self.FindWindowById(
  2255. self.win['anim']['frameIndex']['slider']).Disable()
  2256. self.FindWindowById(
  2257. self.win['anim']['frameIndex']['text']).Disable()
  2258. elif mode == 'play':
  2259. self.FindWindowById(self.win['anim']['record']).Disable()
  2260. self.FindWindowById(self.win['anim']['play']).Enable()
  2261. self.FindWindowById(
  2262. self.win['anim']['frameIndex']['slider']).Enable()
  2263. self.FindWindowById(
  2264. self.win['anim']['frameIndex']['text']).Enable()
  2265. self.FindWindowById(self.win['anim']['pause']).Disable()
  2266. self.FindWindowById(self.win['anim']['stop']).Enable()
  2267. def OnFrameIndex(self, event):
  2268. """Frame index changed (by slider)"""
  2269. index = event.GetInt()
  2270. self.UpdateFrameIndex(index=index, sliderWidget=False)
  2271. def OnFrameIndexText(self, event):
  2272. """Frame index changed by (textCtrl)"""
  2273. index = event.GetValue()
  2274. self.UpdateFrameIndex(index=index, textWidget=False)
  2275. def OnFPS(self, event):
  2276. """Frames per second changed"""
  2277. anim = self.mapWindow.GetAnimation()
  2278. anim.SetFPS(event.GetInt())
  2279. def UpdateFrameIndex(self, index, sliderWidget=True,
  2280. textWidget=True, goToFrame=True):
  2281. """Update frame index"""
  2282. anim = self.mapWindow.GetAnimation()
  2283. # check index
  2284. frameCount = anim.GetFrameCount()
  2285. if index >= frameCount:
  2286. index = frameCount - 1
  2287. if index < 0:
  2288. index = 0
  2289. if sliderWidget:
  2290. slider = self.FindWindowById(
  2291. self.win['anim']['frameIndex']['slider'])
  2292. slider.SetValue(index)
  2293. if textWidget:
  2294. text = self.FindWindowById(self.win['anim']['frameIndex']['text'])
  2295. text.SetValue(int(index))
  2296. # if called from tool window, update frame
  2297. if goToFrame:
  2298. anim.GoToFrame(int(index))
  2299. def UpdateFrameCount(self):
  2300. """Update frame count label"""
  2301. anim = self.mapWindow.GetAnimation()
  2302. count = anim.GetFrameCount()
  2303. self.FindWindowById(self.win['anim']['info']).SetLabel(str(count))
  2304. def OnAnimationFinished(self, mode):
  2305. """Animation finished"""
  2306. anim = self.mapWindow.GetAnimation()
  2307. self.UpdateFrameIndex(index=0)
  2308. slider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
  2309. text = self.FindWindowById(self.win['anim']['frameIndex']['text'])
  2310. if mode == 'record':
  2311. count = anim.GetFrameCount()
  2312. slider.SetMax(count)
  2313. self.UpdateFrameCount()
  2314. self.FindWindowById(self.win['anim']['pause']).Disable()
  2315. self.FindWindowById(self.win['anim']['stop']).Disable()
  2316. self.FindWindowById(self.win['anim']['record']).Enable()
  2317. self.FindWindowById(self.win['anim']['play']).Enable()
  2318. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  2319. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  2320. self.FindWindowById(self.win['anim']['save'][
  2321. 'image']['confirm']).Enable()
  2322. self.mapWindow.render['quick'] = False
  2323. self.mapWindow.Refresh(False)
  2324. def OnAnimationUpdateIndex(self, index, mode):
  2325. """Animation: frame index changed"""
  2326. if mode == 'record':
  2327. self.UpdateFrameCount()
  2328. elif mode == 'play':
  2329. self.UpdateFrameIndex(index=index, goToFrame=False)
  2330. def OnSaveAnimation(self, event):
  2331. """Save animation as a sequence of images"""
  2332. anim = self.mapWindow.GetAnimation()
  2333. prefix = self.FindWindowById(
  2334. self.win['anim']['save']['image']['prefix']).GetValue()
  2335. format = self.FindWindowById(
  2336. self.win['anim']['save']['image']['format']).GetSelection()
  2337. dir = self.FindWindowById(
  2338. self.win['anim']['save']['image']['dir']).GetValue()
  2339. if not prefix:
  2340. GMessage(parent=self,
  2341. message=_("No file prefix given."))
  2342. return
  2343. elif not os.path.exists(dir):
  2344. GMessage(parent=self,
  2345. message=_("Directory %s does not exist.") % dir)
  2346. return
  2347. self.FindWindowById(self.win['anim']['pause']).Disable()
  2348. self.FindWindowById(self.win['anim']['stop']).Enable()
  2349. self.FindWindowById(self.win['anim']['record']).Disable()
  2350. self.FindWindowById(self.win['anim']['play']).Disable()
  2351. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  2352. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  2353. self.FindWindowById(self.win['anim']['save'][
  2354. 'image']['confirm']).Disable()
  2355. anim.SaveAnimationFile(path=dir, prefix=prefix, format=format)
  2356. def OnNewConstant(self, event):
  2357. """Create new surface with constant value"""
  2358. # TODO settings
  2359. name = self.mapWindow.NewConstant()
  2360. win = self.FindWindowById(self.win['constant']['surface'])
  2361. name = _("constant#") + str(name)
  2362. win.Append(name)
  2363. win.SetStringSelection(name)
  2364. self.OnConstantSelection(None)
  2365. self.EnablePage(name='constant', enabled=True)
  2366. self.mapWindow.Refresh(eraseBackground=False)
  2367. # need to update list of surfaces in vector page
  2368. for vtype in ('points', 'lines'):
  2369. checklist = self.FindWindowById(
  2370. self.win['vector'][vtype]['surface'])
  2371. checklist.Append(name)
  2372. win = self.FindWindowById(self.win['vector']['map'])
  2373. win.SetValue(win.GetValue())
  2374. def OnDeleteConstant(self, event):
  2375. """Delete selected constant surface"""
  2376. layerIdx = self.FindWindowById(
  2377. self.win['constant']['surface']).GetSelection()
  2378. if layerIdx == wx.NOT_FOUND:
  2379. return
  2380. name = self.FindWindowById(
  2381. self.win['constant']['surface']).GetStringSelection()
  2382. self.mapWindow.DeleteConstant(layerIdx)
  2383. win = self.FindWindowById(self.win['constant']['surface'])
  2384. win.Delete(layerIdx)
  2385. if win.IsEmpty():
  2386. win.SetValue("")
  2387. self.EnablePage(name='constant', enabled=False)
  2388. else:
  2389. win.SetSelection(0)
  2390. self.OnConstantSelection(None)
  2391. # need to update list of surfaces in vector page
  2392. for vtype in ('points', 'lines'):
  2393. checklist = self.FindWindowById(
  2394. self.win['vector'][vtype]['surface'])
  2395. checklist.Delete(checklist.FindString(name))
  2396. if self.mapDisplay.IsAutoRendered():
  2397. self.mapWindow.Refresh(False)
  2398. def OnConstantSelection(self, event):
  2399. """Constant selected"""
  2400. layerIdx = self.FindWindowById(
  2401. self.win['constant']['surface']).GetSelection()
  2402. if layerIdx == wx.NOT_FOUND:
  2403. return
  2404. name = _("constant#") + str(layerIdx + 1)
  2405. data = self.mapWindow.constants[layerIdx]
  2406. for attr, value in data['constant'].iteritems():
  2407. if attr == 'color':
  2408. value = self._getColorFromString(value)
  2409. if attr in ('color', 'value', 'resolution', 'transp'):
  2410. if attr == 'transp':
  2411. self.FindWindowById(
  2412. self.win['constant'][attr]).SetValue(
  2413. self._getPercent(value))
  2414. self.FindWindowById(self.win['constant'][attr]).SetValue(value)
  2415. def OnSetConstantProp(self, event):
  2416. """Change properties (color, value, resolution)
  2417. of currently selected constant surface"""
  2418. layerIdx = self.FindWindowById(
  2419. self.win['constant']['surface']).GetSelection()
  2420. if layerIdx == wx.NOT_FOUND:
  2421. return
  2422. data = self.mapWindow.constants[layerIdx]
  2423. for attr in ('resolution', 'value', 'transp'):
  2424. data['constant'][attr] = self.FindWindowById(
  2425. self.win['constant'][attr]).GetValue()
  2426. data['constant']['color'] = self._getColorString(
  2427. self.FindWindowById(self.win['constant']['color']).GetValue())
  2428. data['constant']['transp'] = self._getPercent(
  2429. data['constant']['transp'], toPercent=False)
  2430. # update properties
  2431. event = wxUpdateProperties(data=data)
  2432. wx.PostEvent(self.mapWindow, event)
  2433. if self.mapDisplay.IsAutoRendered():
  2434. self.mapWindow.Refresh(False)
  2435. def OnFringe(self, event):
  2436. """Show/hide fringe"""
  2437. data = self.GetLayerData('fringe')['surface']
  2438. sid = data['object']['id']
  2439. elev = self.FindWindowById(self.win['fringe']['elev']).GetValue()
  2440. color = self.FindWindowById(self.win['fringe']['color']).GetValue()
  2441. self._display.SetFringe(
  2442. sid, color, elev, self.FindWindowById(
  2443. self.win['fringe']['nw']).IsChecked(), self.FindWindowById(
  2444. self.win['fringe']['ne']).IsChecked(), self.FindWindowById(
  2445. self.win['fringe']['sw']).IsChecked(), self.FindWindowById(
  2446. self.win['fringe']['se']).IsChecked())
  2447. self.mapWindow.Refresh(False)
  2448. def OnScroll(self, event, win, data):
  2449. """Generic scrolling handler"""
  2450. winName = self.__GetWindowName(win, event.GetId())
  2451. if not winName:
  2452. return
  2453. data[winName] = self.FindWindowById(event.GetId()).GetValue()
  2454. for w in win[winName].itervalues():
  2455. self.FindWindowById(w).SetValue(data[winName])
  2456. event.Skip()
  2457. def AdjustSliderRange(self, slider, value):
  2458. minim, maxim = slider.GetRange()
  2459. if not (minim <= value <= maxim):
  2460. slider.SetRange(min(minim, value), max(maxim, value))
  2461. def _createIsosurfacePanel(self, parent):
  2462. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  2463. vSizer = wx.BoxSizer(wx.HORIZONTAL)
  2464. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  2465. label=" %s " % (_("Isosurface attributes")))
  2466. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2467. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  2468. self.win['volume']['attr'] = {}
  2469. inout = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  2470. label=_("toggle normal direction"))
  2471. gridSizer.Add(
  2472. item=inout, pos=(
  2473. 0, 0), span=(
  2474. 1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  2475. inout.Bind(wx.EVT_CHECKBOX, self.OnInOutMode)
  2476. self.win['volume']['inout'] = inout.GetId()
  2477. row = 1
  2478. for code, attrb in (('topo', _("Isosurface value")),
  2479. ('color', _("Color")),
  2480. ('mask', _("Mask")),
  2481. ('transp', _("Transparency")),
  2482. ('shine', _("Shininess"))):
  2483. self.win['volume'][code] = {}
  2484. # label
  2485. colspan = 1
  2486. if code == 'topo':
  2487. colspan = 2
  2488. gridSizer.Add(
  2489. item=wx.StaticText(
  2490. parent=panel,
  2491. id=wx.ID_ANY,
  2492. label=attrb + ':'),
  2493. pos=(
  2494. row,
  2495. 0),
  2496. span=(
  2497. 1,
  2498. colspan),
  2499. flag=wx.ALIGN_CENTER_VERTICAL)
  2500. if code != 'topo':
  2501. use = wx.Choice(parent=panel, id=wx.ID_ANY, size=(100, -1),
  2502. choices=[_("map")])
  2503. else:
  2504. use = None
  2505. # check for required properties
  2506. if code not in ('topo', 'color', 'shine'):
  2507. use.Insert(item=_("unset"), pos=0)
  2508. self.win['volume'][code]['required'] = False
  2509. else:
  2510. self.win['volume'][code]['required'] = True
  2511. if use and code != 'mask':
  2512. use.Append(item=_('constant'))
  2513. if use:
  2514. self.win['volume'][code]['use'] = use.GetId()
  2515. use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
  2516. gridSizer.Add(item=use, flag=wx.ALIGN_CENTER_VERTICAL,
  2517. pos=(row, 1))
  2518. if code != 'topo':
  2519. map = Select(parent=panel, id=wx.ID_ANY,
  2520. # size = globalvar.DIALOG_GSELECT_SIZE,
  2521. size=(200, -1),
  2522. type="grid3")
  2523. if globalvar.CheckWxVersion([3]):
  2524. self.win['volume'][code]['map'] = map.GetId()
  2525. else:
  2526. self.win['volume'][code]['map'] = map.GetTextCtrl().GetId()
  2527. map.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
  2528. gridSizer.Add(item=map, flag=wx.ALIGN_CENTER_VERTICAL,
  2529. pos=(row, 2))
  2530. else:
  2531. map = None
  2532. if code == 'color':
  2533. color = UserSettings.Get(
  2534. group='nviz', key='volume', subkey=[
  2535. 'color', 'value'])
  2536. value = csel.ColourSelect(panel, id=wx.ID_ANY,
  2537. colour=color,
  2538. size=globalvar.DIALOG_COLOR_SIZE)
  2539. value.Bind(csel.EVT_COLOURSELECT, self.OnVolumeIsosurfMap)
  2540. value.SetName('color')
  2541. elif code == 'mask':
  2542. value = None
  2543. elif code == 'topo':
  2544. value = NumTextCtrl(parent=panel, id=wx.ID_ANY, size=(200, -1),
  2545. style=wx.TE_PROCESS_ENTER)
  2546. value.Bind(wx.EVT_TEXT_ENTER, self.OnVolumeIsosurfMap)
  2547. value.Bind(wx.EVT_KILL_FOCUS, self.OnVolumeIsosurfMap)
  2548. ## value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
  2549. else:
  2550. size = (65, -1)
  2551. value = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=size,
  2552. initial=0)
  2553. if code == 'topo':
  2554. value.SetRange(minVal=-1e9, maxVal=1e9)
  2555. elif code in ('shine', 'transp'):
  2556. value.SetRange(minVal=0, maxVal=100)
  2557. value.Bind(wx.EVT_SPINCTRL, self.OnVolumeIsosurfMap)
  2558. value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
  2559. if value:
  2560. self.win['volume'][code]['const'] = value.GetId()
  2561. if code == 'topo':
  2562. gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL,
  2563. pos=(row, 2))
  2564. else:
  2565. value.Enable(False)
  2566. gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL,
  2567. pos=(row, 3))
  2568. else:
  2569. self.win['volume'][code]['const'] = None
  2570. if code != 'topo':
  2571. # -> enable map / disable constant
  2572. self.SetMapObjUseMap(nvizType='volume', attrb=code)
  2573. row += 1
  2574. boxSizer.Add(item=gridSizer, proportion=1,
  2575. flag=wx.ALL | wx.EXPAND, border=3)
  2576. vSizer.Add(item=boxSizer, proportion=1,
  2577. flag=wx.EXPAND, border=0)
  2578. panel.SetSizer(vSizer)
  2579. return panel
  2580. def _createSlicePanel(self, parent):
  2581. panel = wx.Panel(parent=parent, id=wx.ID_ANY)
  2582. vSizer = wx.BoxSizer(wx.HORIZONTAL)
  2583. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  2584. label=" %s " % (_("Slice attributes")))
  2585. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2586. hSizer = wx.BoxSizer()
  2587. self.win['volume']['slice'] = {}
  2588. hSizer.Add(
  2589. item=wx.StaticText(
  2590. parent=panel,
  2591. id=wx.ID_ANY,
  2592. label=_("Slice parallel to axis:")),
  2593. proportion=0,
  2594. flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT,
  2595. border=3)
  2596. axes = wx.Choice(
  2597. parent=panel, id=wx.ID_ANY, size=(65, -1),
  2598. choices=("X", "Y", "Z"))
  2599. hSizer.Add(axes, proportion=0, flag=wx.ALIGN_LEFT | wx.LEFT, border=3)
  2600. self.win['volume']['slice']['axes'] = axes.GetId()
  2601. axes.Bind(wx.EVT_CHOICE, self.OnVolumeSliceAxes)
  2602. boxSizer.Add(hSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
  2603. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  2604. # text labels
  2605. for i in range(2):
  2606. label = wx.StaticText(parent=panel, id=wx.ID_ANY)
  2607. label.SetName('label_edge_' + str(i))
  2608. gridSizer.Add(item=label, pos=(0, i + 1),
  2609. flag=wx.ALIGN_CENTER)
  2610. for i in range(2, 4):
  2611. label = wx.StaticText(parent=panel, id=wx.ID_ANY)
  2612. label.SetName('label_edge_' + str(i))
  2613. gridSizer.Add(item=label, pos=(3, i - 1),
  2614. flag=wx.ALIGN_CENTER)
  2615. for i in range(2):
  2616. label = wx.StaticText(parent=panel, id=wx.ID_ANY)
  2617. label.SetName('label_coord_' + str(i))
  2618. gridSizer.Add(item=label, pos=(i + 1, 0),
  2619. flag=wx.ALIGN_CENTER_VERTICAL)
  2620. label = wx.StaticText(parent=panel, id=wx.ID_ANY)
  2621. label.SetName('label_coord_2')
  2622. gridSizer.Add(item=label, pos=(4, 0),
  2623. flag=wx.ALIGN_CENTER_VERTICAL)
  2624. # sliders
  2625. for i, coord in enumerate(('x1', 'x2')):
  2626. slider = wx.Slider(
  2627. parent=panel,
  2628. id=wx.ID_ANY,
  2629. minValue=0,
  2630. maxValue=100,
  2631. value=0)
  2632. self.win['volume']['slice']['slider_' + coord] = slider.GetId()
  2633. slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
  2634. slider.Bind(
  2635. wx.EVT_SCROLL_THUMBRELEASE,
  2636. self.OnSlicePositionChanged)
  2637. gridSizer.Add(item=slider, pos=(1, i + 1),
  2638. flag=wx.ALIGN_CENTER | wx.EXPAND)
  2639. for i, coord in enumerate(('y1', 'y2')):
  2640. slider = wx.Slider(
  2641. parent=panel,
  2642. id=wx.ID_ANY,
  2643. minValue=0,
  2644. maxValue=100,
  2645. value=0)
  2646. self.win['volume']['slice']['slider_' + coord] = slider.GetId()
  2647. slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
  2648. slider.Bind(
  2649. wx.EVT_SCROLL_THUMBRELEASE,
  2650. self.OnSlicePositionChanged)
  2651. gridSizer.Add(item=slider, pos=(2, i + 1),
  2652. flag=wx.ALIGN_CENTER | wx.EXPAND)
  2653. for i, coord in enumerate(('z1', 'z2')):
  2654. slider = wx.Slider(
  2655. parent=panel,
  2656. id=wx.ID_ANY,
  2657. minValue=0,
  2658. maxValue=100,
  2659. value=0)
  2660. self.win['volume']['slice']['slider_' + coord] = slider.GetId()
  2661. slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
  2662. slider.Bind(
  2663. wx.EVT_SCROLL_THUMBRELEASE,
  2664. self.OnSlicePositionChanged)
  2665. gridSizer.Add(item=slider, pos=(4, i + 1),
  2666. flag=wx.ALIGN_CENTER | wx.EXPAND)
  2667. gridSizer.AddGrowableCol(0, 1)
  2668. gridSizer.AddGrowableCol(1, 2)
  2669. gridSizer.AddGrowableCol(2, 2)
  2670. boxSizer.Add(item=gridSizer, proportion=1,
  2671. flag=wx.ALL | wx.EXPAND, border=3)
  2672. # transparency, reset
  2673. hSizer = wx.BoxSizer()
  2674. hSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  2675. label=_("Transparency:")), proportion=0,
  2676. flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP, border=7)
  2677. spin = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  2678. min=0, max=100, initial=0)
  2679. spin.Bind(wx.EVT_SPINCTRL, self.OnSliceTransparency)
  2680. self.win['volume']['slice']['transp'] = spin.GetId()
  2681. hSizer.Add(item=spin, proportion=0,
  2682. flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.TOP, border=7)
  2683. hSizer.Add(item=wx.Size(-1, -1), proportion=1,
  2684. flag=wx.EXPAND)
  2685. reset = wx.Button(parent=panel, id=wx.ID_ANY, label=_("Reset"))
  2686. reset.Bind(wx.EVT_BUTTON, self.OnSliceReset)
  2687. self.win['volume']['slice']['reset'] = reset.GetId()
  2688. hSizer.Add(item=reset, proportion=0,
  2689. flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP, border=7)
  2690. boxSizer.Add(hSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
  2691. panel.SetSizer(boxSizer)
  2692. return panel
  2693. def _createControl(self, parent, data, name, range, tooltip=None, bind=(
  2694. None, None, None), sliderHor=True, size=200, floatSlider=False):
  2695. """Add control (Slider + TextCtrl)"""
  2696. data[name] = dict()
  2697. if sliderHor:
  2698. style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
  2699. wx.SL_BOTTOM
  2700. sizeW = (size, -1)
  2701. else:
  2702. style = wx.SL_VERTICAL | wx.SL_AUTOTICKS | \
  2703. wx.SL_INVERSE
  2704. sizeW = (-1, size)
  2705. kwargs = dict(parent=parent, id=wx.ID_ANY,
  2706. minValue=range[0],
  2707. maxValue=range[1],
  2708. style=style,
  2709. size=sizeW)
  2710. if floatSlider:
  2711. slider = FloatSlider(**kwargs)
  2712. else:
  2713. slider = wx.Slider(**kwargs)
  2714. slider.SetName('slider')
  2715. if bind[0]:
  2716. # EVT_SCROLL emits event after slider is released, EVT_SPIN not
  2717. slider.Bind(wx.EVT_SPIN, bind[0])
  2718. if bind[1]:
  2719. slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, bind[1])
  2720. data[name]['slider'] = slider.GetId()
  2721. text = NumTextCtrl(parent=parent, id=wx.ID_ANY, size=(65, -1),
  2722. style=wx.TE_PROCESS_ENTER)
  2723. text.SetName('text')
  2724. if tooltip:
  2725. text.SetToolTipString(tooltip)
  2726. if bind[2]:
  2727. text.Bind(wx.EVT_TEXT_ENTER, bind[2])
  2728. text.Bind(wx.EVT_KILL_FOCUS, bind[2])
  2729. data[name]['text'] = text.GetId()
  2730. def _createCompass(self, panel, sizer, type):
  2731. """Create 'compass' widget for light and view page"""
  2732. w = wx.Button(panel, id=wx.ID_ANY, label=_("W"))
  2733. n = wx.Button(panel, id=wx.ID_ANY, label=_("N"))
  2734. s = wx.Button(panel, id=wx.ID_ANY, label=_("S"))
  2735. e = wx.Button(panel, id=wx.ID_ANY, label=_("E"))
  2736. nw = wx.Button(panel, id=wx.ID_ANY, label=_("NW"))
  2737. ne = wx.Button(panel, id=wx.ID_ANY, label=_("NE"))
  2738. se = wx.Button(panel, id=wx.ID_ANY, label=_("SE"))
  2739. sw = wx.Button(panel, id=wx.ID_ANY, label=_("SW"))
  2740. padding = 15
  2741. if sys.platform == 'darwin':
  2742. padding = 20
  2743. minWidth = sw.GetTextExtent(sw.GetLabel())[0] + padding
  2744. for win, name in zip((w, n, s, e, nw, ne, se, sw),
  2745. ('w', 'n', 's', 'e', 'nw', 'ne', 'se', 'sw')):
  2746. win.SetMinSize((minWidth, -1))
  2747. win.Bind(wx.EVT_BUTTON, self.OnLookFrom)
  2748. win.SetName(type + '_' + name)
  2749. sizer.Add(item=nw, pos=(0, 0), flag=wx.ALIGN_CENTER)
  2750. sizer.Add(item=n, pos=(0, 1), flag=wx.ALIGN_CENTER)
  2751. sizer.Add(item=ne, pos=(0, 2), flag=wx.ALIGN_CENTER)
  2752. sizer.Add(item=e, pos=(1, 2), flag=wx.ALIGN_CENTER)
  2753. sizer.Add(item=se, pos=(2, 2), flag=wx.ALIGN_CENTER)
  2754. sizer.Add(item=s, pos=(2, 1), flag=wx.ALIGN_CENTER)
  2755. sizer.Add(item=sw, pos=(2, 0), flag=wx.ALIGN_CENTER)
  2756. sizer.Add(item=w, pos=(1, 0), flag=wx.ALIGN_CENTER)
  2757. def __GetWindowName(self, data, id):
  2758. for name in data.iterkeys():
  2759. if isinstance(data[name], type({})):
  2760. for win in data[name].itervalues():
  2761. if win == id:
  2762. return name
  2763. else:
  2764. if data[name] == id:
  2765. return name
  2766. return None
  2767. def UpdateSettings(self):
  2768. """Update view from settings values
  2769. stored in self.mapWindow.view dictionary"""
  2770. for control in ('height',
  2771. 'persp',
  2772. 'twist',
  2773. 'z-exag'):
  2774. for win in self.win['view'][control].itervalues():
  2775. try:
  2776. if control == 'height':
  2777. value = int(self.mapWindow.iview[control]['value'])
  2778. else:
  2779. value = self.mapWindow.view[control]['value']
  2780. except KeyError:
  2781. value = -1
  2782. self.FindWindowById(win).SetValue(value)
  2783. viewWin = self.FindWindowById(self.win['view']['position'])
  2784. x, y = viewWin.UpdatePos(self.mapWindow.view['position']['x'],
  2785. self.mapWindow.view['position']['y'])
  2786. viewWin.Draw(pos=(x, y), scale=True)
  2787. viewWin.Refresh(False)
  2788. color = self._getColorString(
  2789. self.mapWindow.view['background']['color'])
  2790. self._display.SetBgColor(str(color))
  2791. self.Update()
  2792. self.mapWindow.Refresh(eraseBackground=False)
  2793. self.mapWindow.render['quick'] = False
  2794. self.mapWindow.Refresh(True)
  2795. def OnShowLightModel(self, event):
  2796. """Show light model"""
  2797. self._display.showLight = event.IsChecked()
  2798. self._display.DrawLightingModel()
  2799. def OnLightChange(self, event):
  2800. """Position of the light changing"""
  2801. winName = self.__GetWindowName(self.win['light'], event.GetId())
  2802. if not winName:
  2803. return
  2804. value = self.FindWindowById(event.GetId()).GetValue()
  2805. self.mapWindow.light['position']['z'] = value
  2806. for win in self.win['light'][winName].itervalues():
  2807. self.FindWindowById(win).SetValue(value)
  2808. self.PostLightEvent()
  2809. event.Skip()
  2810. def OnLightChanged(self, event):
  2811. """Light changed"""
  2812. self.PostLightEvent(refresh=True)
  2813. def OnLightColor(self, event):
  2814. """Color of the light changed"""
  2815. self.mapWindow.light['color'] = tuple(event.GetValue())
  2816. self.PostLightEvent(refresh=True)
  2817. event.Skip()
  2818. def OnLightValue(self, event):
  2819. """Light brightness/ambient changing"""
  2820. data = self.mapWindow.light
  2821. self.OnScroll(event, self.win['light'], data)
  2822. self.PostLightEvent()
  2823. event.Skip()
  2824. def OnBgColor(self, event):
  2825. """Background color changed"""
  2826. color = event.GetValue()
  2827. self.mapWindow.view['background']['color'] = tuple(color)
  2828. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  2829. self._display.SetBgColor(str(color))
  2830. if self.mapDisplay.IsAutoRendered():
  2831. self.mapWindow.Refresh(False)
  2832. def OnSetSurface(self, event):
  2833. """Surface selected, currently used for fringes"""
  2834. name = event.GetString()
  2835. try:
  2836. data = self._getLayerPropertiesByName(
  2837. name, mapType='raster')['surface']
  2838. except:
  2839. self.EnablePage('fringe', False)
  2840. return
  2841. layer = self._getMapLayerByName(name, mapType='raster')
  2842. self.EnablePage('fringe', True)
  2843. def OnSetRaster(self, event):
  2844. """Raster map selected, update surface page"""
  2845. name = event.GetString()
  2846. try:
  2847. data = self._getLayerPropertiesByName(
  2848. name, mapType='raster')['surface']
  2849. except TypeError as e:
  2850. self.EnablePage('surface', False)
  2851. return
  2852. layer = self._getMapLayerByName(name, mapType='raster')
  2853. self.EnablePage('surface', True)
  2854. self.UpdateSurfacePage(layer, data, updateName=False)
  2855. def OnSetVector(self, event):
  2856. """Vector map selected, update properties page"""
  2857. name = event.GetString()
  2858. try:
  2859. data = self._getLayerPropertiesByName(
  2860. name, mapType='vector')['vector']
  2861. except:
  2862. self.EnablePage('vector', False)
  2863. return
  2864. layer = self._getMapLayerByName(name, mapType='vector')
  2865. self.EnablePage('vector', True)
  2866. self.UpdateVectorPage(layer, data, updateName=False)
  2867. def OnSetRaster3D(self, event):
  2868. """3D Raster map selected, update surface page"""
  2869. name = event.GetString()
  2870. try:
  2871. data = self._getLayerPropertiesByName(
  2872. name, mapType='raster_3d')['volume']
  2873. except:
  2874. self.EnablePage('volume', False)
  2875. return
  2876. layer = self._getMapLayerByName(name, mapType='raster_3d')
  2877. self.EnablePage('volume', True)
  2878. self.UpdateVolumePage(layer, data, updateName=False)
  2879. def OnViewChange(self, event):
  2880. """Change view, render in quick mode"""
  2881. # find control
  2882. winName = self.__GetWindowName(self.win['view'], event.GetId())
  2883. if not winName:
  2884. return
  2885. value = self.FindWindowById(event.GetId()).GetValue()
  2886. slider = self.FindWindowById(self.win['view'][winName]['slider'])
  2887. if winName == 'persp' and not (0 <= value <= 180):
  2888. return
  2889. self.AdjustSliderRange(slider=slider, value=value)
  2890. if winName == 'height':
  2891. view = self.mapWindow.iview # internal
  2892. else:
  2893. view = self.mapWindow.view
  2894. if winName == 'z-exag' and value >= 0:
  2895. self.PostViewEvent(zExag=True)
  2896. else:
  2897. self.PostViewEvent(zExag=False)
  2898. if winName in ('persp', 'twist'):
  2899. convert = int
  2900. else:
  2901. convert = float
  2902. view[winName]['value'] = convert(value)
  2903. for win in self.win['view'][winName].itervalues():
  2904. self.FindWindowById(win).SetValue(value)
  2905. self.mapWindow.iview['dir']['use'] = False
  2906. self.mapWindow.render['quick'] = True
  2907. if self.mapDisplay.IsAutoRendered():
  2908. self.mapWindow.Refresh(False)
  2909. event.Skip()
  2910. def OnViewChanged(self, event):
  2911. """View changed, render in full resolution"""
  2912. self.mapWindow.render['quick'] = False
  2913. self.mapWindow.Refresh(False)
  2914. self.UpdateSettings()
  2915. try: # when calling event = None
  2916. event.Skip()
  2917. except AttributeError:
  2918. pass
  2919. def OnViewChangedText(self, event):
  2920. """View changed, render in full resolution"""
  2921. self.mapWindow.render['quick'] = False
  2922. self.OnViewChange(event)
  2923. self.OnViewChanged(None)
  2924. self.Update()
  2925. event.Skip()
  2926. def OnLookAt(self, event):
  2927. """Look here/center"""
  2928. name = self.FindWindowById(event.GetId()).GetName()
  2929. if name == 'center':
  2930. self._display.LookAtCenter()
  2931. focus = self.mapWindow.iview['focus']
  2932. focus['x'], focus['y'], focus['z'] = self._display.GetFocus()
  2933. self.mapWindow.saveHistory = True
  2934. self.mapWindow.Refresh(False)
  2935. elif name == 'top':
  2936. self.mapWindow.view['position']['x'] = 0.5
  2937. self.mapWindow.view['position']['y'] = 0.5
  2938. self.PostViewEvent(zExag=True)
  2939. self.UpdateSettings()
  2940. self.mapWindow.Refresh(False)
  2941. else: # here
  2942. if self.FindWindowById(event.GetId()).GetValue():
  2943. self.mapDisplay.Raise()
  2944. self.mapWindow.mouse['use'] = 'lookHere'
  2945. self.mapWindow.SetNamedCursor('cross')
  2946. else:
  2947. self.mapWindow.mouse['use'] = 'default'
  2948. self.mapWindow.SetNamedCursor('default')
  2949. def OnResetView(self, event):
  2950. """Reset to default view (view page)"""
  2951. self.mapWindow.ResetView()
  2952. self.UpdateSettings()
  2953. self.mapWindow.Refresh(False)
  2954. def OnResetSurfacePosition(self, event):
  2955. """Reset position of surface"""
  2956. for win in self.win['surface']['position'].itervalues():
  2957. if win == self.win['surface']['position']['axis']:
  2958. self.FindWindowById(win).SetSelection(2) # Z
  2959. elif win == self.win['surface']['position']['reset']:
  2960. continue
  2961. else:
  2962. self.FindWindowById(win).SetValue(0)
  2963. data = self.GetLayerData('surface')
  2964. data['surface']['position']['x'] = 0
  2965. data['surface']['position']['y'] = 0
  2966. data['surface']['position']['z'] = 0
  2967. data['surface']['position']['update'] = None
  2968. # update properties
  2969. event = wxUpdateProperties(data=data)
  2970. wx.PostEvent(self.mapWindow, event)
  2971. if self.mapDisplay.IsAutoRendered():
  2972. self.mapWindow.Refresh(False)
  2973. def OnLookFrom(self, event):
  2974. """Position of view/light changed by buttons"""
  2975. name = self.FindWindowById(event.GetId()).GetName()
  2976. buttonName = name.split('_')[1]
  2977. if name.split('_')[0] == 'view':
  2978. type = 'view'
  2979. data = self.mapWindow.view
  2980. else:
  2981. type = 'light'
  2982. data = self.mapWindow.light
  2983. if buttonName == 'n': # north
  2984. data['position']['x'] = 0.5
  2985. data['position']['y'] = 0.0
  2986. elif buttonName == 's': # south
  2987. data['position']['x'] = 0.5
  2988. data['position']['y'] = 1.0
  2989. elif buttonName == 'e': # east
  2990. data['position']['x'] = 1.0
  2991. data['position']['y'] = 0.5
  2992. elif buttonName == 'w': # west
  2993. data['position']['x'] = 0.0
  2994. data['position']['y'] = 0.5
  2995. elif buttonName == 'nw': # north-west
  2996. data['position']['x'] = 0.0
  2997. data['position']['y'] = 0.0
  2998. elif buttonName == 'ne': # north-east
  2999. data['position']['x'] = 1.0
  3000. data['position']['y'] = 0.0
  3001. elif buttonName == 'se': # south-east
  3002. data['position']['x'] = 1.0
  3003. data['position']['y'] = 1.0
  3004. elif buttonName == 'sw': # south-west
  3005. data['position']['x'] = 0.0
  3006. data['position']['y'] = 1.0
  3007. if type == 'view':
  3008. self.PostViewEvent(zExag=True)
  3009. self.UpdateSettings()
  3010. else:
  3011. self.PostLightEvent()
  3012. lightWin = self.FindWindowById(self.win['light']['position'])
  3013. x, y = lightWin.UpdatePos(self.mapWindow.light['position']['x'],
  3014. self.mapWindow.light['position']['y'])
  3015. lightWin.Draw(pos=(x, y), scale=True)
  3016. lightWin.Refresh(False)
  3017. self.mapWindow.render['quick'] = False
  3018. self.mapWindow.Refresh(False)
  3019. def OnMapObjUse(self, event):
  3020. """Set surface attribute -- use -- map/constant"""
  3021. if not self.mapWindow.init:
  3022. return
  3023. wx.Yield()
  3024. # find attribute row
  3025. attrb = self.__GetWindowName(self.win['surface'], event.GetId())
  3026. if not attrb:
  3027. attrb = self.__GetWindowName(self.win['volume'], event.GetId())
  3028. nvizType = 'volume'
  3029. else:
  3030. nvizType = 'surface'
  3031. selection = event.GetSelection()
  3032. if self.win[nvizType][attrb]['required']: # no 'unset'
  3033. selection += 1
  3034. if selection == 0: # unset
  3035. useMap = None
  3036. value = ''
  3037. elif selection == 1: # map
  3038. useMap = True
  3039. value = self.FindWindowById(
  3040. self.win[nvizType][attrb]['map']).GetValue()
  3041. elif selection == 2: # constant
  3042. useMap = False
  3043. if attrb == 'color':
  3044. value = self.FindWindowById(
  3045. self.win[nvizType][attrb]['const']).GetColour()
  3046. value = self._getColorString(value)
  3047. else:
  3048. value = self._getPercent(
  3049. self.FindWindowById(
  3050. self.win[nvizType][attrb]['const']).GetValue(),
  3051. toPercent=False)
  3052. self.SetMapObjUseMap(nvizType=nvizType,
  3053. attrb=attrb, map=useMap)
  3054. name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
  3055. if nvizType == 'surface':
  3056. data = self._getLayerPropertiesByName(name, mapType='raster')
  3057. data[nvizType]['attribute'][attrb] = {'map': useMap,
  3058. 'value': str(value),
  3059. 'update': None}
  3060. else: # volume / isosurface
  3061. data = self._getLayerPropertiesByName(name, mapType='raster_3d')
  3062. list = self.FindWindowById(self.win['volume']['isosurfs'])
  3063. id = list.GetSelection()
  3064. if id != -1:
  3065. data[nvizType]['isosurface'][id][attrb] = {'map': useMap,
  3066. 'value': str(value),
  3067. 'update': None}
  3068. # update properties
  3069. event = wxUpdateProperties(data=data)
  3070. wx.PostEvent(self.mapWindow, event)
  3071. if self.mapDisplay.IsAutoRendered():
  3072. self.mapWindow.Refresh(False)
  3073. def EnablePage(self, name, enabled=True):
  3074. """Enable/disable all widgets on page"""
  3075. for key, item in self.win[name].iteritems():
  3076. if key in ('map', 'surface', 'new', 'planes'):
  3077. continue
  3078. if isinstance(item, types.DictType):
  3079. for skey, sitem in self.win[name][key].iteritems():
  3080. if isinstance(sitem, types.DictType):
  3081. for ssitem in self.win[name][key][skey].itervalues():
  3082. if not isinstance(ssitem, types.BooleanType) and \
  3083. isinstance(ssitem, types.IntType):
  3084. self.FindWindowById(ssitem).Enable(enabled)
  3085. else:
  3086. # type(bool) != types.IntType but
  3087. # isinstance(bool) == types.IntType
  3088. if not isinstance(sitem, types.BooleanType) and \
  3089. isinstance(sitem, types.IntType):
  3090. self.FindWindowById(sitem).Enable(enabled)
  3091. else:
  3092. if not isinstance(item, types.BooleanType) and \
  3093. isinstance(item, types.IntType):
  3094. self.FindWindowById(item).Enable(enabled)
  3095. def SetMapObjUseMap(self, nvizType, attrb, map=None):
  3096. """Update dialog widgets when attribute type changed"""
  3097. if attrb in ('topo', 'color', 'shine'):
  3098. incSel = -1 # decrement selection (no 'unset')
  3099. else:
  3100. incSel = 0
  3101. if nvizType == 'volume' and attrb == 'topo':
  3102. return
  3103. if map is True: # map
  3104. if attrb != 'topo': # changing map topography not allowed
  3105. # not sure why, but here must be disabled both ids, should be
  3106. # fixed!
  3107. self.FindWindowById(
  3108. self.win[nvizType][attrb]['map']).Enable(True)
  3109. if self.win[nvizType][attrb]['const']:
  3110. self.FindWindowById(
  3111. self.win[nvizType][attrb]['const']).Enable(False)
  3112. self.FindWindowById(
  3113. self.win[nvizType][attrb]['use']).SetSelection(
  3114. 1 + incSel)
  3115. elif map is False: # const
  3116. self.FindWindowById(self.win[nvizType][attrb]['map']).Enable(False)
  3117. if self.win[nvizType][attrb]['const']:
  3118. self.FindWindowById(
  3119. self.win[nvizType][attrb]['const']).Enable(True)
  3120. self.FindWindowById(
  3121. self.win[nvizType][attrb]['use']).SetSelection(
  3122. 2 + incSel)
  3123. else: # unset
  3124. self.FindWindowById(
  3125. self.win[nvizType][attrb]['use']).SetSelection(0)
  3126. self.FindWindowById(self.win[nvizType][attrb]['map']).Enable(False)
  3127. if self.win[nvizType][attrb]['const']:
  3128. self.FindWindowById(
  3129. self.win[nvizType][attrb]['const']).Enable(False)
  3130. def OnSurfaceMap(self, event):
  3131. """Set surface attribute"""
  3132. if self.vetoGSelectEvt:
  3133. self.vetoGSelectEvt = False
  3134. return
  3135. self.SetMapObjAttrb(nvizType='surface', winId=event.GetId())
  3136. def SetMapObjAttrb(self, nvizType, winId):
  3137. """Set map object (surface/isosurface) attribute (map/constant)"""
  3138. if not self.mapWindow.init:
  3139. return
  3140. attrb = self.__GetWindowName(self.win[nvizType], winId)
  3141. if not attrb:
  3142. return
  3143. if not (nvizType == 'volume' and attrb == 'topo'):
  3144. selection = self.FindWindowById(
  3145. self.win[nvizType][attrb]['use']).GetSelection()
  3146. if self.win[nvizType][attrb]['required']:
  3147. selection += 1
  3148. if selection == 0: # unset
  3149. useMap = None
  3150. value = ''
  3151. elif selection == 1: # map
  3152. value = self.FindWindowById(
  3153. self.win[nvizType][attrb]['map']).GetValue()
  3154. useMap = True
  3155. else: # constant
  3156. if attrb == 'color':
  3157. value = self.FindWindowById(
  3158. self.win[nvizType][attrb]['const']).GetColour()
  3159. # tuple to string
  3160. value = self._getColorString(value)
  3161. else:
  3162. value = self._getPercent(
  3163. self.FindWindowById(
  3164. self.win[nvizType][attrb]['const']).GetValue(),
  3165. toPercent=False)
  3166. useMap = False
  3167. else:
  3168. useMap = None
  3169. value = self.FindWindowById(
  3170. self.win[nvizType][attrb]['const']).GetValue()
  3171. if not self.pageChanging:
  3172. name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
  3173. if nvizType == 'surface':
  3174. data = self._getLayerPropertiesByName(name, mapType='raster')
  3175. data[nvizType]['attribute'][attrb] = {'map': useMap,
  3176. 'value': str(value),
  3177. 'update': None}
  3178. else:
  3179. data = self._getLayerPropertiesByName(
  3180. name, mapType='raster_3d')
  3181. list = self.FindWindowById(self.win['volume']['isosurfs'])
  3182. id = list.GetSelection()
  3183. if id > -1:
  3184. data[nvizType]['isosurface'][id][attrb] = {
  3185. 'map': useMap, 'value': str(value), 'update': None}
  3186. if attrb == 'topo':
  3187. list = self.FindWindowById(
  3188. self.win['volume']['isosurfs'])
  3189. sel = list.GetSelection()
  3190. list.SetString(sel, "%s %s" % (_("Level"), str(value)))
  3191. list.Check(sel)
  3192. # update properties
  3193. event = wxUpdateProperties(data=data)
  3194. wx.PostEvent(self.mapWindow, event)
  3195. if self.mapDisplay.IsAutoRendered():
  3196. self.mapWindow.Refresh(False)
  3197. def OnSurfaceResolution(self, event):
  3198. """Draw resolution changed"""
  3199. self.SetSurfaceResolution()
  3200. if self.mapDisplay.IsAutoRendered():
  3201. self.mapWindow.Refresh(False)
  3202. def SetSurfaceResolution(self):
  3203. """Set draw resolution"""
  3204. coarse = self.FindWindowById(
  3205. self.win['surface']['draw']['res-coarse']).GetValue()
  3206. fine = self.FindWindowById(
  3207. self.win['surface']['draw']['res-fine']).GetValue()
  3208. data = self.GetLayerData('surface')
  3209. data['surface']['draw']['resolution'] = {'coarse': coarse,
  3210. 'fine': fine,
  3211. 'update': None}
  3212. # update properties
  3213. event = wxUpdateProperties(data=data)
  3214. wx.PostEvent(self.mapWindow, event)
  3215. def SetSurfaceMode(self):
  3216. """Set draw mode"""
  3217. mode = self.FindWindowById(
  3218. self.win['surface']['draw']['mode']).GetSelection()
  3219. style = self.FindWindowById(
  3220. self.win['surface']['draw']['style']).GetSelection()
  3221. if style == 0: # wire
  3222. self.FindWindowById(self.win['surface']['draw'][
  3223. 'wire-color']).Enable(True)
  3224. elif style == 1: # surface
  3225. self.FindWindowById(self.win['surface']['draw'][
  3226. 'wire-color']).Enable(False)
  3227. shade = self.FindWindowById(
  3228. self.win['surface']['draw']['shading']).GetSelection()
  3229. value, desc = self.mapWindow.nvizDefault.GetDrawMode(
  3230. mode, style, shade)
  3231. return value, desc
  3232. def OnSurfaceMode(self, event):
  3233. """Set draw mode"""
  3234. value, desc = self.SetSurfaceMode()
  3235. data = self.GetLayerData('surface')
  3236. data['surface']['draw']['mode'] = {'value': value,
  3237. 'desc': desc,
  3238. 'update': None}
  3239. # update properties
  3240. event = wxUpdateProperties(data=data)
  3241. wx.PostEvent(self.mapWindow, event)
  3242. if self.mapDisplay.IsAutoRendered():
  3243. self.mapWindow.Refresh(False)
  3244. def OnSurfaceModeAll(self, event):
  3245. """Set draw mode (including wire color) for all loaded surfaces"""
  3246. value, desc = self.SetSurfaceMode()
  3247. coarse = self.FindWindowById(
  3248. self.win['surface']['draw']['res-coarse']).GetValue()
  3249. fine = self.FindWindowById(
  3250. self.win['surface']['draw']['res-fine']).GetValue()
  3251. color = self.FindWindowById(
  3252. self.win['surface']['draw']['wire-color']).GetColour()
  3253. cvalue = self._getColorString(color)
  3254. for name in self.mapWindow.GetLayerNames(type='raster'):
  3255. data = self._getLayerPropertiesByName(name, mapType='raster')
  3256. if not data:
  3257. continue # shouldy no happen
  3258. data['surface']['draw']['all'] = True
  3259. data['surface']['draw']['mode'] = {'value': value,
  3260. 'desc': desc,
  3261. 'update': None}
  3262. data['surface']['draw']['resolution'] = {'coarse': coarse,
  3263. 'fine': fine,
  3264. 'update': None}
  3265. data['surface']['draw']['wire-color'] = {'value': cvalue,
  3266. 'update': None}
  3267. # update properties
  3268. event = wxUpdateProperties(data=data)
  3269. wx.PostEvent(self.mapWindow, event)
  3270. if self.mapDisplay.IsAutoRendered():
  3271. self.mapWindow.Refresh(False)
  3272. def _getColorString(self, color):
  3273. """Convert color tuple to R:G:B format
  3274. :param color: tuple
  3275. :return: string R:G:B
  3276. """
  3277. return str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  3278. def _getColorFromString(self, color, delim=':'):
  3279. """Convert color string (R:G:B) to wx.Colour
  3280. :param color: string
  3281. :param delim: delimiter
  3282. :return: wx.Colour instance
  3283. """
  3284. return wx.Colour(*map(int, color.split(delim)))
  3285. def _get3dRange(self, name):
  3286. """Gelper func for getting range of 3d map"""
  3287. ret = RunCommand('r3.info', read=True, flags='r', map=name)
  3288. if ret:
  3289. range = []
  3290. for value in ret.strip('\n').split('\n'):
  3291. range.append(float(value.split('=')[1]))
  3292. return range
  3293. return -1e6, 1e6
  3294. def _getPercent(self, value, toPercent=True):
  3295. """Convert values 0 - 255 to percents and vice versa"""
  3296. value = int(value)
  3297. if toPercent:
  3298. value = int(value / 255. * 100)
  3299. else:
  3300. value = int(value / 100. * 255)
  3301. return value
  3302. def OnSurfaceWireColor(self, event):
  3303. """Set wire color"""
  3304. data = self.GetLayerData('surface')
  3305. value = self._getColorString(event.GetValue())
  3306. data['surface']['draw']['wire-color'] = {'value': value,
  3307. 'update': None}
  3308. # update properties
  3309. event = wxUpdateProperties(data=data)
  3310. wx.PostEvent(self.mapWindow, event)
  3311. if self.mapDisplay.IsAutoRendered():
  3312. self.mapWindow.Refresh(False)
  3313. def OnSurfaceAxis(self, event):
  3314. """Surface position, axis changed"""
  3315. data = self.GetLayerData('surface')
  3316. id = data['surface']['object']['id']
  3317. axis = self.FindWindowById(
  3318. self.win['surface']['position']['axis']).GetSelection()
  3319. slider = self.FindWindowById(self.win['surface']['position']['slider'])
  3320. text = self.FindWindowById(self.win['surface']['position']['text'])
  3321. xydim = self._display.GetLongDim()
  3322. zdim = self._display.GetZRange()
  3323. zdim = zdim[1] - zdim[0]
  3324. x, y, z = self._display.GetSurfacePosition(id)
  3325. if axis == 0: # x
  3326. slider.SetRange(-3 * xydim, 3 * xydim)
  3327. slider.SetValue(x)
  3328. text.SetValue(x)
  3329. elif axis == 1: # y
  3330. slider.SetRange(-3 * xydim, 3 * xydim)
  3331. slider.SetValue(y)
  3332. text.SetValue(y)
  3333. else: # z
  3334. slider.SetRange(-3 * zdim, 3 * zdim)
  3335. slider.SetValue(z)
  3336. text.SetValue(z)
  3337. def OnSurfacePosition(self, event):
  3338. """Surface position"""
  3339. winName = self.__GetWindowName(self.win['surface'], event.GetId())
  3340. if not winName:
  3341. return
  3342. axis = self.FindWindowById(
  3343. self.win['surface']['position']['axis']).GetSelection()
  3344. value = self.FindWindowById(event.GetId()).GetValue()
  3345. slider = self.FindWindowById(self.win['surface'][winName]['slider'])
  3346. self.AdjustSliderRange(slider=slider, value=value)
  3347. for win in self.win['surface']['position'].itervalues():
  3348. if win in (self.win['surface']['position']['axis'],
  3349. self.win['surface']['position']['reset']):
  3350. continue
  3351. else:
  3352. self.FindWindowById(win).SetValue(value)
  3353. data = self.GetLayerData('surface')
  3354. id = data['surface']['object']['id']
  3355. x, y, z = self._display.GetSurfacePosition(id)
  3356. if axis == 0: # x
  3357. x = value
  3358. elif axis == 1: # y
  3359. y = value
  3360. else: # z
  3361. z = value
  3362. data['surface']['position']['x'] = x
  3363. data['surface']['position']['y'] = y
  3364. data['surface']['position']['z'] = z
  3365. data['surface']['position']['update'] = None
  3366. # update properties
  3367. event = wxUpdateProperties(data=data)
  3368. wx.PostEvent(self.mapWindow, event)
  3369. self.mapWindow.render['quick'] = True
  3370. if self.mapDisplay.IsAutoRendered():
  3371. self.mapWindow.Refresh(False)
  3372. # self.UpdatePage('surface')
  3373. def OnSurfacePositionChanged(self, event):
  3374. """Surface position changed"""
  3375. self.mapWindow.render['quick'] = False
  3376. self.mapWindow.Refresh(False)
  3377. def OnSurfacePositionText(self, event):
  3378. """Surface position changed by textctrl"""
  3379. self.OnSurfacePosition(event)
  3380. self.OnSurfacePositionChanged(None)
  3381. def UpdateVectorShow(self, vecType, enabled):
  3382. """Enable/disable lines/points widgets
  3383. :param vecType: vector type (lines, points)
  3384. """
  3385. if vecType != 'lines' and vecType != 'points':
  3386. return False
  3387. for win in self.win['vector'][vecType].keys():
  3388. if win == 'show':
  3389. continue
  3390. if isinstance(self.win['vector'][vecType][win], type({})):
  3391. for swin in self.win['vector'][vecType][win].keys():
  3392. if enabled:
  3393. self.FindWindowById(
  3394. self.win['vector'][vecType][win][swin]).Enable(True)
  3395. else:
  3396. self.FindWindowById(
  3397. self.win['vector'][vecType][win][swin]).Enable(False)
  3398. else:
  3399. if enabled:
  3400. self.FindWindowById(
  3401. self.win['vector'][vecType][win]).Enable(True)
  3402. else:
  3403. self.FindWindowById(
  3404. self.win['vector'][vecType][win]).Enable(False)
  3405. return True
  3406. def OnVectorShow(self, event):
  3407. """Show vector lines/points"""
  3408. winId = event.GetId()
  3409. if winId == self.win['vector']['lines']['show']:
  3410. vecType = 'lines'
  3411. points = False
  3412. else: # points
  3413. vecType = 'points'
  3414. points = True
  3415. checked = event.IsChecked()
  3416. name = self.FindWindowById(self.win['vector']['map']).GetValue()
  3417. items = self.tree.FindItemByData(key='name', value=name)
  3418. for item in items:
  3419. if self.tree.GetLayerInfo(item, key='type') == 'vector':
  3420. break
  3421. data = self.GetLayerData('vector')['vector']
  3422. if checked:
  3423. self.mapWindow.LoadVector(item, points=points, append=False)
  3424. else:
  3425. self.mapWindow.UnloadVector(item, points=points, remove=False)
  3426. self.UpdateVectorShow(vecType, checked)
  3427. if checked:
  3428. try:
  3429. id = data[vecType]['object']['id']
  3430. except KeyError:
  3431. id = -1
  3432. if id > 0:
  3433. self.mapWindow.SetMapObjProperties(item, id, vecType)
  3434. # update properties
  3435. event = wxUpdateProperties(data=data)
  3436. wx.PostEvent(self.mapWindow, event)
  3437. if self.mapDisplay.IsAutoRendered():
  3438. self.mapWindow.Refresh(False)
  3439. event.Skip()
  3440. def OnVectorLinesMode(self, event):
  3441. """Display vector lines on surface/3d"""
  3442. rasters = self.mapWindow.GetLayerNames('raster')
  3443. if event.GetSelection() == 0: # surface
  3444. if len(rasters) < 1:
  3445. self.FindWindowById(
  3446. self.win['vector']['lines']['surface']).Enable(False)
  3447. self.FindWindowById(
  3448. self.win['vector']['lines']['3d']).SetSelection(1)
  3449. return
  3450. self.FindWindowById(
  3451. self.win['vector']['lines']['surface']).Enable(True)
  3452. # set first found surface
  3453. data = self.GetLayerData('vector')
  3454. data['vector']['lines']['mode']['surface'] = rasters[0]
  3455. self.FindWindowById(
  3456. self.win['vector']['lines']['surface']).SetStringSelection(
  3457. rasters[0])
  3458. else: # 3D
  3459. self.FindWindowById(self.win['vector']['lines'][
  3460. 'surface']).Enable(False)
  3461. self.OnVectorLines(event)
  3462. event.Skip()
  3463. def OnVectorLines(self, event):
  3464. """Set vector lines mode, apply changes if auto-rendering is enabled"""
  3465. data = self.GetLayerData('vector')
  3466. width = self.FindWindowById(
  3467. self.win['vector']['lines']['width']).GetValue()
  3468. mode = {}
  3469. if self.FindWindowById(self.win['vector']['lines'][
  3470. '3d']).GetSelection() == 0:
  3471. mode['type'] = 'surface'
  3472. mode['surface'] = {}
  3473. checklist = self.FindWindowById(
  3474. self.win['vector']['lines']['surface'])
  3475. value = list()
  3476. checked = list()
  3477. for surface in range(checklist.GetCount()):
  3478. value.append(checklist.GetString(surface))
  3479. checked.append(checklist.IsChecked(surface))
  3480. mode['surface']['value'] = value
  3481. mode['surface']['show'] = checked
  3482. else:
  3483. mode['type'] = '3d'
  3484. for attrb in ('width', 'mode'):
  3485. data['vector']['lines'][attrb]['update'] = None
  3486. data['vector']['lines']['width']['value'] = width
  3487. data['vector']['lines']['mode'] = mode
  3488. color = self.FindWindowById(
  3489. self.win['vector']['lines']['color']).GetColour()
  3490. if isinstance(color, csel.ColourSelect):
  3491. pass # color picker not yet instantiated
  3492. else:
  3493. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  3494. data['vector']['lines']['color']['update'] = None
  3495. data['vector']['lines']['color']['value'] = color
  3496. # update properties
  3497. event = wxUpdateProperties(data=data)
  3498. wx.PostEvent(self.mapWindow, event)
  3499. if self.mapDisplay.IsAutoRendered():
  3500. self.mapWindow.Refresh(False)
  3501. def OnVectorPointsMode(self, event):
  3502. rasters = self.mapWindow.GetLayerNames('raster')
  3503. if event.GetSelection() == 0: # surface
  3504. if len(rasters) < 1:
  3505. self.FindWindowById(
  3506. self.win['vector']['points']['surface']).Enable(False)
  3507. self.FindWindowById(
  3508. self.win['vector']['points']['3d']).SetSelection(1)
  3509. return
  3510. self.FindWindowById(
  3511. self.win['vector']['points']['surface']).Enable(True)
  3512. # set first found surface
  3513. data = self.GetLayerData('vector')
  3514. data['vector']['points']['mode']['surface']['value'] = rasters
  3515. data['vector']['points']['mode']['3d'] = False
  3516. self.FindWindowById(
  3517. self.win['vector']['points']['surface']).SetStringSelection(
  3518. rasters[0])
  3519. else: # use z coordinate if 3d
  3520. data = self.GetLayerData('vector')
  3521. data['vector']['points']['mode']['3d'] = True
  3522. self.FindWindowById(self.win['vector']['points'][
  3523. 'surface']).Enable(False)
  3524. data['vector']['points']['mode']['update'] = None
  3525. self.OnVectorPoints(event)
  3526. event.Skip()
  3527. def OnVectorHeight(self, event):
  3528. id = event.GetId()
  3529. if id in self.win['vector']['lines']['height'].values():
  3530. vtype = 'lines'
  3531. else:
  3532. vtype = 'points'
  3533. value = self.FindWindowById(id).GetValue()
  3534. slider = self.FindWindowById(
  3535. self.win['vector'][vtype]['height']['slider'])
  3536. self.AdjustSliderRange(slider=slider, value=value)
  3537. for win in self.win['vector'][vtype]['height'].itervalues():
  3538. self.FindWindowById(win).SetValue(value)
  3539. data = self.GetLayerData('vector')
  3540. data['vector'][vtype]['height'] = {'value': value,
  3541. 'update': None}
  3542. # update properties
  3543. event = wxUpdateProperties(data=data)
  3544. wx.PostEvent(self.mapWindow, event)
  3545. self.mapWindow.render['quick'] = True
  3546. self.mapWindow.render['v' + vtype] = True
  3547. self.mapWindow.Refresh(False)
  3548. event.Skip()
  3549. def OnVectorHeightFull(self, event):
  3550. """Vector height changed, render in full resolution"""
  3551. self.OnVectorHeight(event)
  3552. # self.OnVectorSurface(event)
  3553. id = event.GetId()
  3554. if id in self.win['vector']['lines']['height'].values():
  3555. vtype = 'lines'
  3556. else:
  3557. vtype = 'points'
  3558. self.mapWindow.render['quick'] = False
  3559. self.mapWindow.render['v' + vtype] = False
  3560. self.mapWindow.Refresh(False)
  3561. def OnVectorHeightText(self, event):
  3562. """Vector height changed, render in full resolution"""
  3563. # self.OnVectorHeight(event)
  3564. self.OnVectorHeightFull(event)
  3565. def OnVectorSurface(self, event):
  3566. """Reference surface for vector map (lines/points)"""
  3567. id = event.GetId()
  3568. if id == self.win['vector']['lines']['surface']:
  3569. vtype = 'lines'
  3570. else:
  3571. vtype = 'points'
  3572. checkList = self.FindWindowById(self.win['vector'][vtype]['surface'])
  3573. checked = []
  3574. surfaces = []
  3575. for items in range(checkList.GetCount()):
  3576. checked.append(checkList.IsChecked(items))
  3577. surfaces.append(checkList.GetString(items))
  3578. data = self.GetLayerData('vector')
  3579. data['vector'][vtype]['mode']['surface'] = {'value': surfaces,
  3580. 'show': checked}
  3581. data['vector'][vtype]['mode']['update'] = None
  3582. # update properties
  3583. event = wxUpdateProperties(data=data)
  3584. wx.PostEvent(self.mapWindow, event)
  3585. if self.mapDisplay.IsAutoRendered():
  3586. self.mapWindow.Refresh(False)
  3587. def OnVectorPoints(self, event):
  3588. """Set vector points mode, apply changes if auto-rendering is enabled"""
  3589. data = self.GetLayerData('vector')
  3590. size = self.FindWindowById(
  3591. self.win['vector']['points']['size']).GetValue()
  3592. marker = self.FindWindowById(
  3593. self.win['vector']['points']['marker']).GetSelection()
  3594. # width = self.FindWindowById(self.win['vector']['points']['width']).GetValue()
  3595. for attrb in ('size', 'marker'):
  3596. data['vector']['points'][attrb]['update'] = None
  3597. data['vector']['points']['size']['value'] = size
  3598. # data['vector']['points']['width']['value'] = width
  3599. data['vector']['points']['marker']['value'] = marker
  3600. color = self.FindWindowById(
  3601. self.win['vector']['points']['color']).GetColour()
  3602. if isinstance(color, csel.ColourSelect):
  3603. pass # color picker not yet instantiated
  3604. else:
  3605. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  3606. data['vector']['points']['color']['update'] = None
  3607. data['vector']['points']['color']['value'] = color
  3608. # update properties
  3609. event = wxUpdateProperties(data=data)
  3610. wx.PostEvent(self.mapWindow, event)
  3611. if self.mapDisplay.IsAutoRendered():
  3612. self.mapWindow.Refresh(False)
  3613. def OnCheckThematic(self, event):
  3614. """Switch on/off thematic mapping"""
  3615. # can be called with no event to enable/disable button
  3616. if not event:
  3617. ids = (self.win['vector']['points']['thematic']['checkcolor'],
  3618. self.win['vector']['lines']['thematic']['checkcolor'],
  3619. self.win['vector']['points']['thematic']['checksize'],
  3620. self.win['vector']['lines']['thematic']['checkwidth'])
  3621. else:
  3622. ids = (event.GetId(),)
  3623. for id in ids:
  3624. if id in self.win['vector']['points']['thematic'].values():
  3625. vtype = 'points'
  3626. if id == self.win['vector'][vtype]['thematic']['checkcolor']:
  3627. attrType = 'color'
  3628. else:
  3629. attrType = 'size'
  3630. else:
  3631. vtype = 'lines'
  3632. if id == self.win['vector'][vtype]['thematic']['checkcolor']:
  3633. attrType = 'color'
  3634. else:
  3635. attrType = 'width'
  3636. check = self.win['vector'][vtype]['thematic']['check' + attrType]
  3637. button = self.win['vector'][vtype]['thematic']['button' + attrType]
  3638. if self.FindWindowById(check).GetValue():
  3639. checked = True
  3640. else:
  3641. checked = False
  3642. self.FindWindowById(button).Enable(checked)
  3643. data = self.GetLayerData('vector')
  3644. # decide if use GRASSRGB column
  3645. if attrType == 'color':
  3646. name = self.FindWindowById(
  3647. self.win['vector']['map']).GetValue()
  3648. if not data['vector'][vtype]['thematic']['rgbcolumn']:
  3649. try:
  3650. id = data['vector'][vtype]['object']['id']
  3651. # if GRASSRGB exists and color table doesn't, use GRGB
  3652. if self.HasGRASSRGB(name) and \
  3653. not self._display.CheckColorTable(id=id, type=vtype):
  3654. data['vector'][vtype]['thematic'][
  3655. 'rgbcolumn'] = 'GRASSRGB'
  3656. except KeyError:
  3657. pass
  3658. data['vector'][vtype]['thematic']['use' + attrType] = checked
  3659. data['vector'][vtype]['thematic']['update'] = None
  3660. # update properties
  3661. event = wxUpdateProperties(data=data)
  3662. wx.PostEvent(self.mapWindow, event)
  3663. if self.mapDisplay.IsAutoRendered():
  3664. self.mapWindow.Refresh(False)
  3665. def HasGRASSRGB(self, name):
  3666. """Check if GRASSRGB column exist."""
  3667. column = False
  3668. dbInfo = VectorDBInfo(name)
  3669. if len(dbInfo.layers):
  3670. table = dbInfo.layers[1]['table']
  3671. if 'GRASSRGB' in dbInfo.GetTableDesc(table):
  3672. column = True
  3673. return column
  3674. def OnSetThematic(self, event):
  3675. """Set options for thematic points"""
  3676. if event.GetId() in self.win['vector']['points']['thematic'].values():
  3677. vtype = 'points'
  3678. else:
  3679. vtype = 'lines'
  3680. if event.GetId() == self.win['vector'][vtype][
  3681. 'thematic']['buttoncolor']:
  3682. attrType = 'color'
  3683. elif vtype == 'points':
  3684. attrType = 'size'
  3685. else:
  3686. attrType = 'width'
  3687. ctable = ThematicVectorTable(self, vtype, attributeType=attrType)
  3688. ctable.CentreOnScreen()
  3689. ctable.Show()
  3690. def UpdateIsosurfButtons(self, list):
  3691. """Enable/disable buttons 'add', 'delete',
  3692. 'move up', 'move down'"""
  3693. nitems = list.GetCount()
  3694. add = self.FindWindowById(self.win['volume']['btnAdd'])
  3695. delete = self.FindWindowById(self.win['volume']['btnDelete'])
  3696. moveDown = self.FindWindowById(self.win['volume']['btnMoveDown'])
  3697. moveUp = self.FindWindowById(self.win['volume']['btnMoveUp'])
  3698. if nitems >= wxnviz.MAX_ISOSURFS:
  3699. # disable add button on max
  3700. add.Enable(False)
  3701. else:
  3702. add.Enable(True)
  3703. if nitems < 1:
  3704. # disable 'delete' if only one item in the lis
  3705. delete.Enable(False)
  3706. else:
  3707. delete.Enable(True)
  3708. if list.GetSelection() >= nitems - 1:
  3709. # disable 'move-down' if last
  3710. moveDown.Enable(False)
  3711. else:
  3712. moveDown.Enable(True)
  3713. if list.GetSelection() < 1:
  3714. # disable 'move-up' if first
  3715. moveUp.Enable(False)
  3716. else:
  3717. moveUp.Enable(True)
  3718. def OnVolumeMode(self, event):
  3719. """Change mode isosurfaces/slices"""
  3720. mode = self.FindWindowById(
  3721. self.win['volume']['draw']['mode']).GetSelection()
  3722. data = self.GetLayerData('volume')['volume']
  3723. sizer = self.isoPanel.GetContainingSizer()
  3724. sizer = self.slicePanel.GetContainingSizer()
  3725. listBox = self.FindWindowByName('listStaticBox')
  3726. if mode == 0:
  3727. sizer.Show(self.isoPanel)
  3728. sizer.Hide(self.slicePanel)
  3729. listBox.SetLabel(" %s " % _("List of isosurfaces"))
  3730. data['draw']['mode']['value'] = 0
  3731. data['draw']['mode']['desc'] = 'isosurface'
  3732. else:
  3733. sizer.Hide(self.isoPanel)
  3734. sizer.Show(self.slicePanel)
  3735. listBox.SetLabel(" %s " % _("List of slices"))
  3736. data['draw']['mode']['value'] = 1
  3737. data['draw']['mode']['desc'] = 'slice'
  3738. if event:
  3739. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3740. layer = self._getMapLayerByName(name, mapType='raster_3d')
  3741. self.UpdateVolumePage(layer, data, updateName=False)
  3742. sizer.Layout()
  3743. listBox.GetParent().Fit()
  3744. def OnVolumeDrawMode(self, event):
  3745. """Set isosurface/slice draw mode"""
  3746. self.SetVolumeDrawMode(event.GetSelection())
  3747. def OnVolumeDrawBox(self, event):
  3748. """Set wire box drawing"""
  3749. data = self.GetLayerData('volume')['volume']
  3750. vid = data['object']['id']
  3751. checked = self.FindWindowById(
  3752. self.win['volume']['draw']['box']).GetValue()
  3753. self._display.SetVolumeDrawBox(vid, checked)
  3754. data['draw']['box']['enabled'] = checked
  3755. if self.mapDisplay.IsAutoRendered():
  3756. self.mapWindow.Refresh(False)
  3757. def SetVolumeDrawMode(self, selection):
  3758. """Set isosurface draw mode"""
  3759. data = self.GetLayerData('volume')['volume']
  3760. id = data['object']['id']
  3761. mode = 0
  3762. if selection == 0:
  3763. mode |= wxnviz.DM_FLAT
  3764. else:
  3765. mode |= wxnviz.DM_GOURAUD
  3766. if self.FindWindowById(self.win['volume']['draw'][
  3767. 'mode']).GetSelection() == 0:
  3768. self._display.SetIsosurfaceMode(id, mode)
  3769. data['draw']['shading']['isosurface']['desc'] = 'gouraud'
  3770. data['draw']['shading']['isosurface']['value'] = mode
  3771. else:
  3772. self._display.SetSliceMode(id, mode)
  3773. data['draw']['shading']['slice']['desc'] = 'flat'
  3774. data['draw']['shading']['slice']['value'] = mode
  3775. if self.mapDisplay.IsAutoRendered():
  3776. self.mapWindow.Refresh(False)
  3777. def OnVolumeResolution(self, event):
  3778. """Set isosurface/slice draw resolution"""
  3779. self.SetVolumeResolution(event.GetInt())
  3780. def SetVolumeResolution(self, res):
  3781. """Set isosurface draw resolution"""
  3782. data = self.GetLayerData('volume')['volume']
  3783. id = data['object']['id']
  3784. if self.FindWindowById(self.win['volume']['draw'][
  3785. 'mode']).GetSelection() == 0:
  3786. self._display.SetIsosurfaceRes(id, res)
  3787. data['draw']['resolution']['isosurface']['value'] = res
  3788. else:
  3789. self._display.SetSliceRes(id, res)
  3790. data['draw']['resolution']['slice']['value'] = res
  3791. if self.mapDisplay.IsAutoRendered():
  3792. self.mapWindow.Refresh(False)
  3793. def OnInOutMode(self, event):
  3794. """Change isosurfaces mode inout"""
  3795. data = self.GetLayerData('volume')['volume']
  3796. id = data['object']['id']
  3797. isosurfId = self.FindWindowById(
  3798. self.win['volume']['isosurfs']).GetSelection()
  3799. ret = self._display.SetIsosurfaceInOut(id, isosurfId, event.GetInt())
  3800. if ret == 1:
  3801. data['isosurface'][isosurfId]['inout']['value'] = event.GetInt()
  3802. if self.mapDisplay.IsAutoRendered():
  3803. self.mapWindow.Refresh(False)
  3804. def OnVolumeIsosurfMap(self, event):
  3805. """Set surface attribute"""
  3806. if self.vetoGSelectEvt:
  3807. self.vetoGSelectEvt = False
  3808. return
  3809. self.SetMapObjAttrb(nvizType='volume', winId=event.GetId())
  3810. def OnVolumeCheck(self, event):
  3811. """Isosurface/slice checked (->load) or unchecked (->unload)"""
  3812. if self.FindWindowById(self.win['volume']['draw'][
  3813. 'mode']).GetSelection() == 0:
  3814. mode = 'isosurf'
  3815. else:
  3816. mode = 'slice'
  3817. index = event.GetSelection()
  3818. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3819. data = self.GetLayerData('volume')['volume']
  3820. vid = data['object']['id']
  3821. id = event.GetSelection()
  3822. if mode == 'isosurf':
  3823. if list.IsChecked(index):
  3824. if 'transp' in data['isosurface'][id] and\
  3825. data['isosurface'][id]['transp']['map'] is not None:
  3826. if data['isosurface'][id]['transp']['map']:
  3827. map = True
  3828. value = data['isosurface'][id]['transp']['value']
  3829. elif data['isosurface'][id]['transp']['map'] is not None:
  3830. map = False
  3831. value = data['isosurface'][id]['transp']['value']
  3832. self._display.SetIsosurfaceTransp(vid, id, map, value)
  3833. else:
  3834. self._display.SetIsosurfaceTransp(vid, id, False, "0")
  3835. else:
  3836. # disable -> make transparent
  3837. self._display.SetIsosurfaceTransp(vid, id, False, "255")
  3838. else:
  3839. if list.IsChecked(index):
  3840. value = data['slice'][id]['transp']['value']
  3841. self._display.SetSliceTransp(vid, id, value)
  3842. else:
  3843. # disable -> make transparent
  3844. self._display.SetSliceTransp(vid, id, 255)
  3845. if self.mapDisplay.IsAutoRendered():
  3846. self.mapWindow.Refresh(False)
  3847. def OnVolumeSelect(self, event):
  3848. """Isosurface/Slice item selected"""
  3849. if self.FindWindowById(self.win['volume']['draw'][
  3850. 'mode']).GetSelection() == 0:
  3851. mode = 'isosurf'
  3852. else:
  3853. mode = 'slice'
  3854. winUp = self.FindWindowById(self.win['volume']['btnMoveUp'])
  3855. winDown = self.FindWindowById(self.win['volume']['btnMoveDown'])
  3856. selection = event.GetSelection()
  3857. if selection == -1:
  3858. return
  3859. elif selection == 0:
  3860. winUp.Enable(False)
  3861. if not winDown.IsEnabled():
  3862. winDown.Enable()
  3863. elif selection == self.FindWindowById(event.GetId()).GetCount() - 1:
  3864. winDown.Enable(False)
  3865. if not winUp.IsEnabled():
  3866. winUp.Enable()
  3867. else:
  3868. if not winDown.IsEnabled():
  3869. winDown.Enable()
  3870. if not winUp.IsEnabled():
  3871. winUp.Enable()
  3872. # update dialog
  3873. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3874. layer = self._getMapLayerByName(name, mapType='raster_3d')
  3875. if mode == 'isosurf':
  3876. data = self.GetLayerData('volume')['volume'][
  3877. 'isosurface'][selection]
  3878. self.UpdateVolumeIsosurfPage(data)
  3879. else:
  3880. data = self.GetLayerData('volume')['volume']['slice'][selection]
  3881. self.UpdateVolumeSlicePage(data)
  3882. def OnVolumeAdd(self, event):
  3883. """Add new isosurface/slice to the list"""
  3884. if self.FindWindowById(self.win['volume']['draw'][
  3885. 'mode']).GetSelection() == 0:
  3886. mode = 'isosurf'
  3887. else:
  3888. mode = 'slice'
  3889. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3890. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3891. layer = self._getMapLayerByName(name, mapType='raster_3d')
  3892. data = self.GetLayerData('volume')['volume']
  3893. id = data['object']['id']
  3894. sel = list.GetSelection()
  3895. if mode == 'isosurf':
  3896. isosurfData = self.mapWindow.nvizDefault.SetIsosurfaceDefaultProp()
  3897. if isosurfData['color']['map']:
  3898. isosurfData['color']['value'] = layer.name
  3899. level = isosurfData['topo']['value'] = round(
  3900. self._get3dRange(name=layer.name)[0], 2)
  3901. if sel < 0 or sel >= list.GetCount() - 1:
  3902. item = list.Append(item=_("Level {level}").format(level=level))
  3903. else:
  3904. list.Insert(item=_("Level {level}").format(level=level),
  3905. pos=sel + 1) # append
  3906. item = sel + 1
  3907. else:
  3908. sliceData = self.mapWindow.nvizDefault.SetSliceDefaultProp()
  3909. axis = ("X", "Y", "Z")[sliceData['position']['axis']]
  3910. if sel < 0 or sel >= list.GetCount() - 1:
  3911. item = list.Append(
  3912. item=_("Slice parallel to {axis}").format(
  3913. axis=axis))
  3914. else:
  3915. list.Insert(
  3916. item=_("Slice parallel to {axis}").format(
  3917. axis=axis), pos=sel + 1) # append
  3918. item = sel + 1
  3919. list.Check(item)
  3920. list.SetSelection(item)
  3921. if mode == 'isosurf':
  3922. data['isosurface'].insert(item, isosurfData)
  3923. # add isosurface
  3924. self._display.AddIsosurface(id, float(level))
  3925. else:
  3926. data['slice'].insert(item, sliceData)
  3927. # add isosurface
  3928. nslice = self._display.AddSlice(id)
  3929. self._display.SetSlicePosition(
  3930. id, nslice - 1, sliceData['position']['x1'],
  3931. sliceData['position']['x2'],
  3932. sliceData['position']['y1'],
  3933. sliceData['position']['y2'],
  3934. sliceData['position']['z1'],
  3935. sliceData['position']['z2'],
  3936. sliceData['position']['axis'])
  3937. # update properties
  3938. event = wxUpdateProperties(data=data)
  3939. wx.PostEvent(self.mapWindow, event)
  3940. # update buttons
  3941. self.UpdateIsosurfButtons(list)
  3942. if mode == 'isosurf':
  3943. self.UpdateVolumeIsosurfPage(isosurfData)
  3944. else:
  3945. self.UpdateVolumeSlicePage(sliceData)
  3946. if self.mapDisplay.IsAutoRendered():
  3947. self.mapWindow.Refresh(False)
  3948. event.Skip()
  3949. def OnVolumeDelete(self, event):
  3950. """Remove isosurface/slice from list"""
  3951. if self.FindWindowById(self.win['volume']['draw'][
  3952. 'mode']).GetSelection() == 0:
  3953. mode = 'isosurf'
  3954. else:
  3955. mode = 'slice'
  3956. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3957. # remove item from list
  3958. id = list.GetSelection()
  3959. list.Delete(id)
  3960. # select last item
  3961. if list.GetCount() > 0:
  3962. list.SetSelection(list.GetCount() - 1)
  3963. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3964. layer = self._getMapLayerByName(name, mapType='raster_3d')
  3965. data = self.GetLayerData('volume')['volume']
  3966. vid = data['object']['id']
  3967. # delete isosurface
  3968. if mode == 'isosurf':
  3969. del data['isosurface'][id]
  3970. self._display.DeleteIsosurface(vid, id)
  3971. else:
  3972. del data['slice'][id]
  3973. self._display.DeleteSlice(vid, id)
  3974. # update buttons
  3975. if list.GetCount() > 0:
  3976. if mode == 'isosurf':
  3977. self.UpdateVolumeIsosurfPage(
  3978. data['isosurface'][list.GetSelection()])
  3979. else:
  3980. self.UpdateVolumeSlicePage(data['slice'][list.GetSelection()])
  3981. else:
  3982. if mode == 'isosurf':
  3983. self.UpdateVolumeIsosurfPage(data['attribute'])
  3984. else:
  3985. self.UpdateVolumeSlicePage(None)
  3986. self.UpdateIsosurfButtons(list)
  3987. if self.mapDisplay.IsAutoRendered():
  3988. self.mapWindow.Refresh(False)
  3989. event.Skip()
  3990. def OnVolumeMoveUp(self, event):
  3991. """Move isosurface/slice up in the list"""
  3992. if self.FindWindowById(self.win['volume']['draw'][
  3993. 'mode']).GetSelection() == 0:
  3994. mode = 'isosurf'
  3995. else:
  3996. mode = 'slice'
  3997. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3998. sel = list.GetSelection()
  3999. if sel < 1:
  4000. return # this should not happen
  4001. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  4002. layer = self._getMapLayerByName(name, mapType='raster_3d')
  4003. data = self.GetLayerData('volume')['volume']
  4004. id = data['object']['id']
  4005. # move item up
  4006. text = list.GetStringSelection()
  4007. list.Insert(item=text, pos=sel - 1)
  4008. list.Check(sel - 1)
  4009. list.SetSelection(sel - 1)
  4010. list.Delete(sel + 1)
  4011. if mode == 'isosurf':
  4012. data['isosurface'].insert(sel - 1, data['isosurface'][sel])
  4013. del data['isosurface'][sel + 1]
  4014. self._display.MoveIsosurface(id, sel, True)
  4015. else:
  4016. data['slice'].insert(sel - 1, data['slice'][sel])
  4017. del data['slice'][sel + 1]
  4018. self._display.MoveSlice(id, sel, True)
  4019. # update buttons
  4020. self.UpdateIsosurfButtons(list)
  4021. if self.mapDisplay.IsAutoRendered():
  4022. self.mapWindow.Refresh(False)
  4023. event.Skip()
  4024. def OnVolumeMoveDown(self, event):
  4025. """Move isosurface/slice down in the list"""
  4026. if self.FindWindowById(self.win['volume']['draw'][
  4027. 'mode']).GetSelection() == 0:
  4028. mode = 'isosurf'
  4029. else:
  4030. mode = 'slice'
  4031. list = self.FindWindowById(self.win['volume'][mode + 's'])
  4032. sel = list.GetSelection()
  4033. if sel >= list.GetCount() - 1:
  4034. return # this should not happen
  4035. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  4036. layer = self._getMapLayerByName(name, mapType='raster_3d')
  4037. data = self.GetLayerData('volume')['volume']
  4038. id = data['object']['id']
  4039. # move item up
  4040. text = list.GetStringSelection()
  4041. list.Insert(item=text, pos=sel + 2)
  4042. list.Check(sel + 2)
  4043. list.SetSelection(sel + 2)
  4044. list.Delete(sel)
  4045. if mode == 'isosurf':
  4046. data['isosurface'].insert(sel + 2, data['isosurface'][sel])
  4047. del data['isosurface'][sel]
  4048. self._display.MoveIsosurface(id, sel, False)
  4049. else:
  4050. data['slice'].insert(sel + 2, data['slice'][sel])
  4051. del data['slice'][sel]
  4052. self._display.MoveSlice(id, sel, False)
  4053. # update buttons
  4054. self.UpdateIsosurfButtons(list)
  4055. if self.mapDisplay.IsAutoRendered():
  4056. self.mapWindow.Refresh(False)
  4057. event.Skip()
  4058. def OnVolumePositionChanged(self, event):
  4059. """Volume position changed"""
  4060. self.mapWindow.render['quick'] = False
  4061. self.mapWindow.Refresh(False)
  4062. def OnVolumePosition(self, event):
  4063. """Volume position"""
  4064. winName = self.__GetWindowName(self.win['volume'], event.GetId())
  4065. if not winName:
  4066. return
  4067. axis = self.FindWindowById(
  4068. self.win['volume']['position']['axis']).GetSelection()
  4069. value = self.FindWindowById(event.GetId()).GetValue()
  4070. slider = self.FindWindowById(self.win['volume'][winName]['slider'])
  4071. self.AdjustSliderRange(slider=slider, value=value)
  4072. for win in self.win['volume']['position'].itervalues():
  4073. if win in (self.win['volume']['position']['axis'],
  4074. self.win['volume']['position']['reset']):
  4075. continue
  4076. else:
  4077. self.FindWindowById(win).SetValue(value)
  4078. data = self.GetLayerData('volume')
  4079. id = data['volume']['object']['id']
  4080. x, y, z = self._display.GetVolumePosition(id)
  4081. if axis == 0: # x
  4082. x = value
  4083. elif axis == 1: # y
  4084. y = value
  4085. else: # z
  4086. z = value
  4087. data['volume']['position']['x'] = x
  4088. data['volume']['position']['y'] = y
  4089. data['volume']['position']['z'] = z
  4090. data['volume']['position']['update'] = None
  4091. # update properties
  4092. event = wxUpdateProperties(data=data)
  4093. wx.PostEvent(self.mapWindow, event)
  4094. self.mapWindow.render['quick'] = True
  4095. if self.mapDisplay.IsAutoRendered():
  4096. self.mapWindow.Refresh(False)
  4097. def OnVolumeAxis(self, event):
  4098. """Volume position, axis changed"""
  4099. data = self.GetLayerData('volume')
  4100. id = data['volume']['object']['id']
  4101. axis = self.FindWindowById(
  4102. self.win['volume']['position']['axis']).GetSelection()
  4103. slider = self.FindWindowById(self.win['volume']['position']['slider'])
  4104. text = self.FindWindowById(self.win['volume']['position']['text'])
  4105. xydim = self._display.GetLongDim()
  4106. zdim = self._display.GetZRange()
  4107. zdim = zdim[1] - zdim[0]
  4108. x, y, z = self._display.GetVolumePosition(id)
  4109. if axis == 0: # x
  4110. slider.SetRange(-3 * xydim, 3 * xydim)
  4111. slider.SetValue(x)
  4112. text.SetValue(x)
  4113. elif axis == 1: # y
  4114. slider.SetRange(-3 * xydim, 3 * xydim)
  4115. slider.SetValue(y)
  4116. text.SetValue(y)
  4117. else: # z
  4118. slider.SetRange(-3 * zdim, 3 * zdim)
  4119. slider.SetValue(z)
  4120. text.SetValue(z)
  4121. def OnVolumePositionText(self, event):
  4122. """Volume position changed by textctrl"""
  4123. self.OnVolumePosition(event)
  4124. self.OnVolumePositionChanged(None)
  4125. def OnResetVolumePosition(self, event):
  4126. """Reset position of volume"""
  4127. for win in self.win['volume']['position'].itervalues():
  4128. if win == self.win['volume']['position']['axis']:
  4129. self.FindWindowById(win).SetSelection(2) # Z
  4130. elif win == self.win['volume']['position']['reset']:
  4131. continue
  4132. else:
  4133. self.FindWindowById(win).SetValue(0)
  4134. data = self.GetLayerData('volume')
  4135. data['volume']['position']['x'] = 0
  4136. data['volume']['position']['y'] = 0
  4137. data['volume']['position']['z'] = 0
  4138. data['volume']['position']['update'] = None
  4139. # update properties
  4140. event = wxUpdateProperties(data=data)
  4141. wx.PostEvent(self.mapWindow, event)
  4142. if self.mapDisplay.IsAutoRendered():
  4143. self.mapWindow.Refresh(False)
  4144. def OnVolumeSliceAxes(self, event):
  4145. """Slice axis changed"""
  4146. self.UpdateSliceLabels()
  4147. data = self.GetLayerData('volume')
  4148. list = self.FindWindowById(self.win['volume']['slices'])
  4149. sel = list.GetSelection()
  4150. if sel < 0:
  4151. return
  4152. axis = self.FindWindowById(
  4153. self.win['volume']['slice']['axes']).GetSelection()
  4154. data['volume']['slice'][sel]['position']['axis'] = axis
  4155. data['volume']['slice'][sel]['position']['update'] = None
  4156. axis = ("X", "Y", "Z")[axis]
  4157. list.SetString(sel, "%s %s" % (_("Slice parallel to"), axis))
  4158. list.Check(sel)
  4159. # update properties
  4160. event = wxUpdateProperties(data=data)
  4161. wx.PostEvent(self.mapWindow, event)
  4162. if self.mapDisplay.IsAutoRendered():
  4163. self.mapWindow.Refresh(False)
  4164. def OnSliceTransparency(self, event):
  4165. """Slice transparency changed"""
  4166. data = self.GetLayerData('volume')
  4167. list = self.FindWindowById(self.win['volume']['slices'])
  4168. sel = list.GetSelection()
  4169. if sel < 0:
  4170. return
  4171. val = self.FindWindowById(
  4172. self.win['volume']['slice']['transp']).GetValue()
  4173. data['volume']['slice'][sel]['transp'][
  4174. 'value'] = self._getPercent(val, toPercent=False)
  4175. data['volume']['slice'][sel]['transp']['update'] = None
  4176. # update properties
  4177. event = wxUpdateProperties(data=data)
  4178. wx.PostEvent(self.mapWindow, event)
  4179. if self.mapDisplay.IsAutoRendered():
  4180. self.mapWindow.Refresh(False)
  4181. def OnSliceReset(self, event):
  4182. """Slice position reset"""
  4183. data = self.GetLayerData('volume')
  4184. list = self.FindWindowById(self.win['volume']['slices'])
  4185. sel = list.GetSelection()
  4186. if sel < 0:
  4187. return
  4188. for coord, val in zip(
  4189. ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'),
  4190. (0, 1, 0, 1, 0, 1, 0)):
  4191. data['volume']['slice'][sel]['position'][coord] = val
  4192. data['volume']['slice'][sel]['position']['update'] = None
  4193. self.UpdateVolumeSlicePage(data['volume']['slice'][sel])
  4194. # update properties
  4195. event = wxUpdateProperties(data=data)
  4196. wx.PostEvent(self.mapWindow, event)
  4197. if self.mapDisplay.IsAutoRendered():
  4198. self.mapWindow.Refresh(False)
  4199. def OnSlicePositionChange(self, event):
  4200. """Slice position is changing"""
  4201. data = self.GetLayerData('volume')
  4202. list = self.FindWindowById(self.win['volume']['slices'])
  4203. sel = list.GetSelection()
  4204. if sel < 0:
  4205. return
  4206. win = self.win['volume']['slice']
  4207. winId = event.GetId()
  4208. value = event.GetInt() / 100.
  4209. for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
  4210. if win['slider_' + coord] == winId:
  4211. data['volume']['slice'][sel]['position'][coord] = value
  4212. data['volume']['slice'][sel]['position']['update'] = None
  4213. break
  4214. self.mapWindow.render['quick'] = True
  4215. # update properties
  4216. event = wxUpdateProperties(data=data)
  4217. wx.PostEvent(self.mapWindow, event)
  4218. if self.mapDisplay.IsAutoRendered():
  4219. self.mapWindow.Refresh(False)
  4220. def OnSlicePositionChanged(self, event):
  4221. """Slice position is changed"""
  4222. self.mapWindow.render['quick'] = False
  4223. if self.mapDisplay.IsAutoRendered():
  4224. self.mapWindow.Refresh(False)
  4225. def OnCPlaneSelection(self, event):
  4226. """Cutting plane selected"""
  4227. plane = self.FindWindowById(
  4228. self.win['cplane']['planes']).GetStringSelection()
  4229. try:
  4230. planeIndex = int(plane.split()[-1]) - 1
  4231. self.EnablePage("cplane", enabled=True)
  4232. except:
  4233. planeIndex = -1
  4234. self.EnablePage("cplane", enabled=False)
  4235. self.mapWindow.SelectCPlane(planeIndex)
  4236. if planeIndex >= 0:
  4237. self.mapWindow.UpdateCPlane(
  4238. planeIndex, changes=[
  4239. 'rotation', 'position', 'shading'])
  4240. if self.mapDisplay.IsAutoRendered():
  4241. self.mapWindow.Refresh(False)
  4242. self.UpdateCPlanePage(planeIndex)
  4243. def OnCPlaneChanging(self, event):
  4244. """Cutting plane is changing"""
  4245. plane = self.FindWindowById(
  4246. self.win['cplane']['planes']).GetStringSelection()
  4247. try:
  4248. planeIndex = int(plane.split()[-1]) - 1
  4249. except: # TODO disabled page
  4250. planeIndex = -1
  4251. if event.GetId() in (self.win['cplane']['rotation']['rot'].values() +
  4252. self.win['cplane']['rotation']['tilt'].values()):
  4253. action = 'rotation'
  4254. else:
  4255. action = 'position'
  4256. data = self.mapWindow.cplanes[planeIndex][action]
  4257. self.OnScroll(event, self.win['cplane'][action], data)
  4258. self.mapWindow.render['quick'] = True
  4259. event = wxUpdateCPlane(update=(action,), current=planeIndex)
  4260. wx.PostEvent(self.mapWindow, event)
  4261. if self.mapDisplay.IsAutoRendered():
  4262. self.mapWindow.Refresh(False)
  4263. def OnCPlaneChangeDone(self, event):
  4264. """Cutting plane change done"""
  4265. self.mapWindow.render['quick'] = False
  4266. if self.mapDisplay.IsAutoRendered():
  4267. self.mapWindow.Refresh(False)
  4268. def OnCPlaneChangeText(self, event):
  4269. """Cutting plane changed by textctrl"""
  4270. for axis in ('x', 'y', 'z'):
  4271. if event.GetId() == self.win['cplane']['position'][axis]['text']:
  4272. value = self.FindWindowById(event.GetId()).GetValue()
  4273. slider = self.FindWindowById(
  4274. self.win['cplane']['position'][axis]['slider'])
  4275. self.AdjustSliderRange(slider=slider, value=value)
  4276. self.OnCPlaneChanging(event=event)
  4277. self.OnCPlaneChangeDone(None)
  4278. def OnCPlaneShading(self, event):
  4279. """Cutting plane shading changed"""
  4280. shading = self.FindWindowById(
  4281. self.win['cplane']['shading']).GetSelection()
  4282. plane = self.FindWindowById(
  4283. self.win['cplane']['planes']).GetStringSelection()
  4284. try:
  4285. planeIndex = int(plane.split()[-1]) - 1
  4286. except: # TODO disabled page
  4287. planeIndex = -1
  4288. self.mapWindow.cplanes[planeIndex]['shading'] = shading
  4289. event = wxUpdateCPlane(update=('shading',), current=planeIndex)
  4290. wx.PostEvent(self.mapWindow, event)
  4291. self.OnCPlaneChangeDone(None)
  4292. def OnCPlaneReset(self, event):
  4293. """Reset current cutting plane"""
  4294. plane = self.FindWindowById(
  4295. self.win['cplane']['planes']).GetStringSelection()
  4296. try:
  4297. planeIndex = int(plane.split()[-1]) - 1
  4298. except: # TODO disabled page
  4299. planeIndex = -1
  4300. self.mapWindow.cplanes[planeIndex] = copy.deepcopy(
  4301. UserSettings.Get(group='nviz', key='cplane'))
  4302. self.mapWindow.cplanes[planeIndex]['on'] = True
  4303. event = wxUpdateCPlane(
  4304. update=(
  4305. 'position',
  4306. 'rotation',
  4307. 'shading'),
  4308. current=planeIndex)
  4309. wx.PostEvent(self.mapWindow, event)
  4310. self.OnCPlaneChangeDone(None)
  4311. self.UpdateCPlanePage(planeIndex)
  4312. def OnDecorationPlacement(self, event):
  4313. """Place an arrow/scalebar by clicking on display"""
  4314. if event.GetId() == self.win['decoration']['arrow']['place']:
  4315. type = 'arrow'
  4316. elif event.GetId() == self.win['decoration']['scalebar']['place']:
  4317. type = 'scalebar'
  4318. else:
  4319. return
  4320. if event.GetInt():
  4321. self.mapDisplay.Raise()
  4322. self.mapWindow.mouse['use'] = type
  4323. self.mapWindow.SetNamedCursor('cross')
  4324. else:
  4325. self.mapWindow.mouse['use'] = 'default'
  4326. self.mapWindow.SetNamedCursor('default')
  4327. def OnArrowDelete(self, event):
  4328. """Delete arrow"""
  4329. self._display.DeleteArrow()
  4330. self.mapWindow.decoration['arrow']['show'] = False
  4331. self.FindWindowById(self.win['decoration'][
  4332. 'arrow']['delete']).Disable()
  4333. self.mapWindow.Refresh(False)
  4334. def OnScalebarDelete(self, event):
  4335. """Delete scalebar"""
  4336. choice = self.FindWindowById(
  4337. self.win['decoration']['scalebar']['choice'])
  4338. choiceIndex = choice.GetSelection()
  4339. index = choice.GetClientData(choiceIndex)
  4340. if index == wx.NOT_FOUND:
  4341. return
  4342. self._display.DeleteScalebar(id=index)
  4343. self.FindWindowById(self.win['decoration']['scalebar'][
  4344. 'choice']).Delete(choiceIndex)
  4345. if not choice.IsEmpty():
  4346. choice.SetSelection(choice.GetCount() - 1)
  4347. self.DisableScalebarControls()
  4348. self.mapWindow.Refresh(False)
  4349. def AddScalebar(self, scalebarNum):
  4350. choice = self.FindWindowById(
  4351. self.win['decoration']['scalebar']['choice'])
  4352. choice.Append(_("Scalebar %d") % (scalebarNum + 1), scalebarNum)
  4353. choice.SetSelection(choice.GetCount() - 1)
  4354. self.DisableScalebarControls()
  4355. def AddArrow(self):
  4356. self.FindWindowById(self.win['decoration']['arrow']['delete']).Enable()
  4357. def DisableScalebarControls(self):
  4358. choice = self.FindWindowById(
  4359. self.win['decoration']['scalebar']['choice'])
  4360. self.FindWindowById(
  4361. self.win['decoration']['scalebar']['delete']).Enable(
  4362. not choice.IsEmpty())
  4363. self.FindWindowById(
  4364. self.win['decoration']['scalebar']['choice']).Enable(
  4365. not choice.IsEmpty())
  4366. def OnDecorationProp(self, event):
  4367. """Set arrow/scalebar properties"""
  4368. if event.GetId() in self.win['decoration']['arrow'].values():
  4369. type = 'arrow'
  4370. elif event.GetId() in self.win['decoration']['scalebar'].values():
  4371. type = 'scalebar'
  4372. else:
  4373. return
  4374. color = self.FindWindowById(
  4375. self.win['decoration'][type]['color']).GetValue()
  4376. size = self.FindWindowById(
  4377. self.win['decoration'][type]['size']).GetValue()
  4378. if type == 'arrow':
  4379. self.mapWindow.decoration[type][
  4380. 'color'] = self._getColorString(color)
  4381. self.mapWindow.decoration[type]['size'] = size
  4382. elif type == 'scalebar'and self.mapWindow.decoration['scalebar']:
  4383. for scalebar in self.mapWindow.decoration[type]:
  4384. scalebar['color'] = self._getColorString(color)
  4385. scalebar['size'] = size
  4386. if type == 'arrow' and self.mapWindow.decoration['arrow']['show']:
  4387. self._display.SetArrow(
  4388. self.mapWindow.decoration['arrow']['position']['x'],
  4389. self.mapWindow.decoration['arrow']['position']['y'],
  4390. self.mapWindow.decoration['arrow']['size'],
  4391. self.mapWindow.decoration['arrow']['color'])
  4392. self._display.DrawArrow()
  4393. elif type == 'scalebar' and self.mapWindow.decoration['scalebar']:
  4394. ids = []
  4395. choice = self.FindWindowById(
  4396. self.win['decoration']['scalebar']['choice'])
  4397. for index in range(choice.GetCount()):
  4398. ids.append(choice.GetClientData(index))
  4399. for scalebar in self.mapWindow.decoration[type]:
  4400. if scalebar['id'] in ids:
  4401. self._display.SetScalebar(scalebar['id'],
  4402. scalebar['position']['x'],
  4403. scalebar['position']['y'],
  4404. scalebar['size'],
  4405. scalebar['color'])
  4406. self._display.DrawScalebar()
  4407. self.mapWindow.Refresh(False)
  4408. def UpdatePage(self, pageId):
  4409. """Update dialog (selected page)"""
  4410. self.pageChanging = True
  4411. Debug.msg(1, "NvizToolWindow.UpdatePage(): %s", pageId)
  4412. if pageId == 'view':
  4413. self.SetPage('view')
  4414. hmin = self.mapWindow.iview['height']['min']
  4415. hmax = self.mapWindow.iview['height']['max']
  4416. hval = self.mapWindow.iview['height']['value']
  4417. zmin = self.mapWindow.view['z-exag']['min']
  4418. zmax = self.mapWindow.view['z-exag']['max']
  4419. zval = self.mapWindow.view['z-exag']['value']
  4420. for control in ('slider', 'text'):
  4421. try:
  4422. self.FindWindowById(
  4423. self.win['view']['height'][control]).SetRange(
  4424. hmin, hmax)
  4425. except OverflowError:
  4426. hmin = self.mapWindow.iview['height']['min'] = 0
  4427. hmax = self.mapWindow.iview['height']['max'] = 10000
  4428. hval = self.mapWindow.iview['height']['value'] = 5000
  4429. self.FindWindowById(
  4430. self.win['view']['height'][control]).SetRange(
  4431. hmin, hmax)
  4432. self.FindWindowById(
  4433. self.win['view']['z-exag'][control]).SetRange(zmin, zmax)
  4434. self.FindWindowById(
  4435. self.win['view']['height'][control]).SetValue(hval)
  4436. self.FindWindowById(
  4437. self.win['view']['z-exag'][control]).SetValue(zval)
  4438. self.FindWindowById(
  4439. self.win['view']['background']['color']).SetColour(
  4440. self.mapWindow.view['background']['color'])
  4441. tval = self.mapWindow.view['twist']['value']
  4442. pval = self.mapWindow.view['persp']['value']
  4443. for control in ('slider', 'text'):
  4444. self.FindWindowById(
  4445. self.win['view']['twist'][control]).SetValue(tval)
  4446. self.FindWindowById(
  4447. self.win['view']['persp'][control]).SetValue(pval)
  4448. elif pageId in ('surface', 'vector', 'volume'):
  4449. name = self.FindWindowById(self.win[pageId]['map']).GetValue()
  4450. data = self.GetLayerData(pageId)
  4451. if data:
  4452. if pageId == 'surface':
  4453. layer = self._getMapLayerByName(name, mapType='raster')
  4454. if layer:
  4455. self.UpdateSurfacePage(layer, data['surface'])
  4456. elif pageId == 'vector':
  4457. layer = self._getMapLayerByName(name, mapType='vector')
  4458. if layer:
  4459. self.UpdateVectorPage(layer, data['vector'])
  4460. elif pageId == 'volume':
  4461. layer = self._getMapLayerByName(name, mapType='raster_3d')
  4462. if layer:
  4463. self.UpdateVolumePage(layer, data['volume'])
  4464. elif pageId == 'light':
  4465. zval = self.mapWindow.light['position']['z']
  4466. bval = self.mapWindow.light['bright']
  4467. aval = self.mapWindow.light['ambient']
  4468. for control in ('slider', 'text'):
  4469. self.FindWindowById(
  4470. self.win['light']['z'][control]).SetValue(zval)
  4471. self.FindWindowById(
  4472. self.win['light']['bright'][control]).SetValue(bval)
  4473. self.FindWindowById(
  4474. self.win['light']['ambient'][control]).SetValue(aval)
  4475. self.FindWindowById(
  4476. self.win['light']['color']).SetColour(
  4477. self.mapWindow.light['color'])
  4478. self.FindWindowById(self.win['light']['position']).PostDraw()
  4479. elif pageId == 'fringe':
  4480. win = self.FindWindowById(self.win['fringe']['map'])
  4481. win.SetValue(
  4482. self.FindWindowById(
  4483. self.win['surface']['map']).GetValue())
  4484. elif pageId == 'decoration':
  4485. win = self.FindWindowById(self.win['decoration']['arrow']['size'])
  4486. win.SetValue(self.mapWindow.decoration['arrow']['size'])
  4487. win = self.FindWindowById(
  4488. self.win['decoration']['scalebar']['size'])
  4489. win.SetValue(self.mapWindow._getDecorationSize())
  4490. elif pageId == 'constant':
  4491. if self.mapWindow.constants:
  4492. surface = self.FindWindowById(self.win['constant']['surface'])
  4493. for item in self.mapWindow.constants:
  4494. surface.Append(_("constant#") +
  4495. str(item['constant']['object']['name']))
  4496. surface.SetSelection(0)
  4497. self.OnConstantSelection(None)
  4498. self.EnablePage('constant', True)
  4499. elif pageId == 'cplane':
  4500. count = self._display.GetCPlanesCount()
  4501. choices = [_("None"), ]
  4502. for plane in range(count):
  4503. choices.append("%s %i" % (_("Plane"), plane + 1))
  4504. self.FindWindowById(self.win['cplane']['planes']).SetItems(choices)
  4505. current = 0
  4506. for i, cplane in enumerate(self.mapWindow.cplanes):
  4507. if cplane['on']:
  4508. current = i + 1
  4509. self.FindWindowById(
  4510. self.win['cplane']['planes']).SetSelection(current)
  4511. xyRange, zRange = self._display.GetXYRange(), self._display.GetZRange()
  4512. if xyRange > 0: # GTK warning
  4513. self.FindWindowById(self.win['cplane']['position']['x'][
  4514. 'slider']).SetRange(-xyRange / 2., xyRange / 2.)
  4515. self.FindWindowById(self.win['cplane']['position']['y'][
  4516. 'slider']).SetRange(-xyRange / 2., xyRange / 2.)
  4517. if zRange[1] - zRange[0] > 1:
  4518. self.FindWindowById(
  4519. self.win['cplane']['position']['z']['slider']).SetRange(
  4520. zRange[0], zRange[1])
  4521. self.FindWindowById(
  4522. self.win['cplane']['position']['z']['slider']).SetValue(
  4523. zRange[0])
  4524. self.FindWindowById(
  4525. self.win['cplane']['position']['z']['text']).SetValue(
  4526. zRange[0])
  4527. self.OnCPlaneSelection(None)
  4528. elif pageId == 'animation':
  4529. self.UpdateAnimationPage()
  4530. self.Update()
  4531. self.pageChanging = False
  4532. def UpdateAnimationPage(self):
  4533. """Update animation page"""
  4534. # wrap help text according to tool window
  4535. help = self.FindWindowById(self.win['anim']['help'])
  4536. width = help.GetGrandParent().GetSizeTuple()[0]
  4537. help.Wrap(width - 15)
  4538. anim = self.mapWindow.GetAnimation()
  4539. if anim.Exists():
  4540. self.FindWindowById(self.win['anim']['play']).Enable()
  4541. else:
  4542. self.UpdateFrameIndex(index=0)
  4543. self.UpdateFrameCount()
  4544. self.FindWindowById(self.win['anim']['play']).Disable()
  4545. self.FindWindowById(self.win['anim']['record']).Enable()
  4546. self.FindWindowById(self.win['anim']['pause']).Disable()
  4547. self.FindWindowById(self.win['anim']['stop']).Disable()
  4548. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  4549. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  4550. def UpdateCPlanePage(self, index):
  4551. """Update widgets according to selected clip plane"""
  4552. if index == -1:
  4553. return
  4554. data = self.mapWindow.cplanes[index]
  4555. for widget in ('text', 'slider'):
  4556. for axes in ('x', 'y', 'z'):
  4557. self.FindWindowById(
  4558. self.win['cplane']['position'][axes][widget]).SetValue(
  4559. data['position'][axes])
  4560. for each in ('tilt', 'rot'):
  4561. self.FindWindowById(
  4562. self.win['cplane']['rotation'][each][widget]).SetValue(
  4563. data['rotation'][each])
  4564. self.FindWindowById(
  4565. self.win['cplane']['shading']).SetSelection(
  4566. data['shading'])
  4567. def UpdateSurfacePage(self, layer, data, updateName=True):
  4568. """Update surface page"""
  4569. desc = grass.raster_info(layer.name)['title']
  4570. if updateName:
  4571. self.FindWindowById(
  4572. self.win['surface']['map']).SetValue(
  4573. layer.name)
  4574. self.FindWindowById(self.win['surface']['desc']).SetLabel(desc)
  4575. # attributes
  4576. if layer and layer.type == 'raster':
  4577. self.vetoGSelectEvt = True
  4578. self.FindWindowById(
  4579. self.win['surface']['color']['map']).SetValue(
  4580. layer.name)
  4581. else:
  4582. self.FindWindowById(
  4583. self.win['surface']['color']['map']).SetValue('')
  4584. self.SetMapObjUseMap(nvizType='surface',
  4585. attrb='color', map=True) # -> map
  4586. if 'color' in data['attribute']:
  4587. value = data['attribute']['color']['value']
  4588. if data['attribute']['color']['map']:
  4589. self.FindWindowById(
  4590. self.win['surface']['color']['map']).SetValue(value)
  4591. else: # constant
  4592. color = map(int, value.split(':'))
  4593. self.FindWindowById(
  4594. self.win['surface']['color']['const']).SetColour(color)
  4595. self.SetMapObjUseMap(
  4596. nvizType='surface', attrb='color',
  4597. map=data['attribute']['color']['map'])
  4598. self.SetMapObjUseMap(
  4599. nvizType='surface', attrb='shine',
  4600. map=data['attribute']['shine']['map'])
  4601. value = data['attribute']['shine']['value']
  4602. if data['attribute']['shine']['map']:
  4603. self.FindWindowById(
  4604. self.win['surface']['shine']['map']).SetValue(value)
  4605. else:
  4606. self.FindWindowById(
  4607. self.win['surface']['shine']['const']).SetValue(
  4608. self._getPercent(value))
  4609. if 'transp' in data['attribute']:
  4610. value = data['attribute']['transp']['value']
  4611. if data['attribute']['transp']['map']:
  4612. self.FindWindowById(
  4613. self.win['surface']['color']['map']).SetValue(value)
  4614. else:
  4615. self.FindWindowById(
  4616. self.win['surface']['transp']['const']).SetValue(
  4617. self._getPercent(value))
  4618. self.SetMapObjUseMap(
  4619. nvizType='surface',
  4620. attrb='transp',
  4621. map=data['attribute']['transp']['map'])
  4622. else:
  4623. self.SetMapObjUseMap(nvizType='surface', attrb='transp', map=None)
  4624. #
  4625. # draw
  4626. #
  4627. for control, drawData in data['draw'].iteritems():
  4628. if control == 'all': # skip 'all' property
  4629. continue
  4630. if control == 'resolution':
  4631. self.FindWindowById(self.win['surface']['draw'][
  4632. 'res-coarse']).SetValue(drawData['coarse'])
  4633. self.FindWindowById(self.win['surface']['draw'][
  4634. 'res-fine']).SetValue(drawData['fine'])
  4635. continue
  4636. if control == 'mode':
  4637. if drawData['desc']['mode'] == 'coarse':
  4638. self.FindWindowById(
  4639. self.win['surface']['draw']['mode']).SetSelection(0)
  4640. elif drawData['desc']['mode'] == 'fine':
  4641. self.FindWindowById(
  4642. self.win['surface']['draw']['mode']).SetSelection(1)
  4643. else: # both
  4644. self.FindWindowById(
  4645. self.win['surface']['draw']['mode']).SetSelection(2)
  4646. if drawData['desc']['style'] == 'wire':
  4647. self.FindWindowById(
  4648. self.win['surface']['draw']['style']).SetSelection(0)
  4649. else: # surface
  4650. self.FindWindowById(
  4651. self.win['surface']['draw']['style']).SetSelection(1)
  4652. if drawData['desc']['shading'] == 'flat':
  4653. self.FindWindowById(
  4654. self.win['surface']['draw']['shading']).SetSelection(0)
  4655. else: # gouraud
  4656. self.FindWindowById(
  4657. self.win['surface']['draw']['shading']).SetSelection(1)
  4658. continue
  4659. value = drawData['value']
  4660. win = self.FindWindowById(self.win['surface']['draw'][control])
  4661. name = win.GetName()
  4662. if name == "selection":
  4663. win.SetSelection(value)
  4664. elif name == "colour":
  4665. color = map(int, value.split(':'))
  4666. win.SetColour(color)
  4667. else:
  4668. win.SetValue(value)
  4669. #
  4670. # position
  4671. #
  4672. self.OnSurfaceAxis(None)
  4673. # enable/disable res widget + set draw mode
  4674. self.OnSurfaceMode(event=None)
  4675. def UpdateVectorPage(self, layer, data, updateName=True):
  4676. """Update vector page"""
  4677. vInfo = grass.vector_info_topo(layer.GetName())
  4678. if not vInfo:
  4679. return
  4680. if vInfo['map3d']:
  4681. desc = _("Vector map is 3D")
  4682. enable = False
  4683. else:
  4684. desc = _("Vector map is 2D")
  4685. enable = True
  4686. desc += " - " + _("%(features)d features (%(points)d points)") % \
  4687. {'features': vInfo['primitives'], 'points': vInfo['points']}
  4688. if updateName:
  4689. self.FindWindowById(self.win['vector']['map']).SetValue(layer.name)
  4690. self.FindWindowById(self.win['vector']['desc']).SetLabel(desc)
  4691. self.FindWindowById(self.win['vector']['lines']['3d']).Enable(enable)
  4692. for v in ('lines', 'points'):
  4693. self.FindWindowById(
  4694. self.win['vector'][v]['surface']).Enable(enable)
  4695. self.FindWindowById(self.win['vector'][v]['height'][
  4696. 'slider']).Enable(enable)
  4697. self.FindWindowById(
  4698. self.win['vector'][v]['height']['text']).Enable(enable)
  4699. if data[v]['thematic']['usecolor']:
  4700. check = self.FindWindowById(
  4701. self.win['vector'][v]['thematic']['checkcolor'])
  4702. check.SetValue(data[v]['thematic']['usecolor'])
  4703. if 'usesize' in data[v]['thematic'] and data[
  4704. v]['thematic']['usesize']:
  4705. check = self.FindWindowById(
  4706. self.win['vector'][v]['thematic']['checksize'])
  4707. check.SetValue(data[v]['thematic']['usesize'])
  4708. elif 'usewidth' in data[v]['thematic'] and data[v]['thematic']['usewidth']:
  4709. check = self.FindWindowById(
  4710. self.win['vector'][v]['thematic']['checkwidth'])
  4711. check.SetValue(data[v]['thematic']['usewidth'])
  4712. self.OnCheckThematic(None)
  4713. #
  4714. # lines
  4715. #
  4716. showLines = self.FindWindowById(self.win['vector']['lines']['show'])
  4717. if 'object' in data['lines']:
  4718. showLines.SetValue(True)
  4719. else:
  4720. showLines.SetValue(False)
  4721. if (vInfo['lines'] + vInfo['boundaries']) > 0:
  4722. showLines.Enable(True)
  4723. else:
  4724. showLines.Enable(False)
  4725. self.UpdateVectorShow('lines', showLines.IsChecked())
  4726. width = self.FindWindowById(self.win['vector']['lines']['width'])
  4727. width.SetValue(data['lines']['width']['value'])
  4728. color = self.FindWindowById(self.win['vector']['lines']['color'])
  4729. color.SetValue(map(int, data['lines']['color']['value'].split(':')))
  4730. for vtype in ('lines', 'points'):
  4731. if vtype == 'lines':
  4732. display = self.FindWindowById(
  4733. self.win['vector']['lines']['3d'])
  4734. if vInfo['map3d']:
  4735. items = [_("on surface(s):"), _("as 3D")]
  4736. else:
  4737. items = [_("on surface")]
  4738. display.SetItems(items)
  4739. if data[vtype]['mode']['type'] == '3d':
  4740. display.SetSelection(1)
  4741. else:
  4742. display.SetSelection(0)
  4743. if data[vtype]['mode']['type'] == 'surface':
  4744. rasters = self.mapWindow.GetLayerNames('raster')
  4745. constants = self.mapWindow.GetLayerNames('constant')
  4746. surfaces = rasters + constants
  4747. surfaceWin = self.FindWindowById(
  4748. self.win['vector'][vtype]['surface'])
  4749. surfaceWin.SetItems(surfaces)
  4750. for idx, surface in enumerate(surfaces):
  4751. try: # TODO fix this mess
  4752. selected = data[vtype]['mode']['surface']['show'][idx]
  4753. except (TypeError, IndexError, KeyError):
  4754. selected = False
  4755. surfaceWin.Check(idx, selected)
  4756. for type in ('slider', 'text'):
  4757. win = self.FindWindowById(
  4758. self.win['vector']['lines']['height'][type])
  4759. win.SetValue(data['lines']['height']['value'])
  4760. #
  4761. # points
  4762. #
  4763. showPoints = self.FindWindowById(self.win['vector']['points']['show'])
  4764. if 'object' in data['points']:
  4765. showPoints.SetValue(True)
  4766. else:
  4767. showPoints.SetValue(False)
  4768. if (vInfo['points'] + vInfo['centroids']) > 0:
  4769. showPoints.Enable(True)
  4770. else:
  4771. showPoints.Enable(False)
  4772. self.UpdateVectorShow('points', showPoints.IsChecked())
  4773. # size, width, marker, color
  4774. for prop in ('size', 'marker', 'color'):
  4775. win = self.FindWindowById(self.win['vector']['points'][prop])
  4776. name = win.GetName()
  4777. if name == 'selection':
  4778. win.SetSelection(data['points'][prop]['value'])
  4779. elif name == 'color':
  4780. color = map(int, data['points'][prop]['value'].split(':'))
  4781. win.SetValue(color)
  4782. else:
  4783. win.SetValue(data['points'][prop]['value'])
  4784. win = self.FindWindowById(self.win['vector']['points']['3d'])
  4785. if vInfo['map3d']:
  4786. items = [_("on surface(s):"), _("as 3D")]
  4787. else:
  4788. items = [_("on surface")]
  4789. win.SetItems(items)
  4790. if data['points']['mode'].get('3d', False):
  4791. win.SetSelection(1)
  4792. else:
  4793. win.SetSelection(0)
  4794. # self.OnCheckThematic(None)
  4795. # height
  4796. for type in ('slider', 'text'):
  4797. win = self.FindWindowById(
  4798. self.win['vector']['points']['height'][type])
  4799. win.SetValue(data['points']['height']['value'])
  4800. def UpdateVolumePage(self, layer, data, updateName=True):
  4801. """Update volume page"""
  4802. if updateName:
  4803. self.FindWindowById(self.win['volume']['map']).SetValue(layer.name)
  4804. # draw
  4805. for control, idata in data['draw'].iteritems():
  4806. if control == 'all': # skip 'all' property
  4807. continue
  4808. win = self.FindWindowById(self.win['volume']['draw'][control])
  4809. if control == 'mode':
  4810. value = data['draw']['mode']['value']
  4811. if control == 'shading':
  4812. if data['draw']['shading'][data['draw']
  4813. ['mode']['desc']]['desc'] == 'flat':
  4814. value = 0
  4815. else:
  4816. value = 1
  4817. if control == 'resolution':
  4818. value = idata[data['draw']['mode']['desc']]['value']
  4819. if control == 'box':
  4820. value = idata['enabled']
  4821. if win.GetName() == "selection":
  4822. win.SetSelection(value)
  4823. else:
  4824. win.SetValue(value)
  4825. self.OnVolumeMode(None)
  4826. id = data['object']['id']
  4827. if data['draw']['mode']['desc'] == 'isosurface':
  4828. self._display.SetIsosurfaceMode(
  4829. id, data['draw']['shading']['isosurface']['value'])
  4830. self._display.SetIsosurfaceRes(
  4831. id, data['draw']['resolution']['isosurface']['value'])
  4832. else:
  4833. self._display.SetSliceMode(
  4834. id, data['draw']['shading']['slice']['value'])
  4835. self._display.SetSliceRes(
  4836. id, data['draw']['resolution']['slice']['value'])
  4837. box = self.FindWindowById(self.win['volume']['isosurfs'])
  4838. if data['draw']['mode']['desc'] == 'isosurface':
  4839. isosurfaces = []
  4840. for iso in data['isosurface']:
  4841. level = iso['topo']['value']
  4842. isosurfaces.append("%s %s" % (_("Level"), level))
  4843. box.Set(isosurfaces)
  4844. for i in range(len(isosurfaces)):
  4845. box.Check(i)
  4846. if data['isosurface']:
  4847. box.SetSelection(0)
  4848. self.UpdateVolumeIsosurfPage(data['isosurface'][0])
  4849. else:
  4850. self.UpdateVolumeIsosurfPage(data['attribute'])
  4851. else:
  4852. slices = []
  4853. for slice in data['slice']:
  4854. axis = ("X", "Y", "Z")[slice['position']['axis']]
  4855. slices.append("%s %s" % (_("Slice parallel to"), axis))
  4856. box.Set(slices)
  4857. for i in range(len(slices)):
  4858. box.Check(i)
  4859. if data['slice']:
  4860. box.SetSelection(0)
  4861. self.UpdateVolumeSlicePage(data['slice'][0])
  4862. else:
  4863. self.UpdateVolumeSlicePage(None)
  4864. #
  4865. # position
  4866. #
  4867. if 'z' in data['position']:
  4868. zval = data['position']['z']
  4869. self.FindWindowById(
  4870. self.win['volume']['position']['axis']).SetSelection(2)
  4871. for control in ('slider', 'text'):
  4872. self.FindWindowById(
  4873. self.win['volume']['position'][control]).SetValue(zval)
  4874. # set topo range
  4875. mapRange = self._get3dRange(name=layer.name)
  4876. desc = self.FindWindowById(self.win['volume']['desc'])
  4877. desc.SetLabel(
  4878. "%s %.2f - %.2f" %
  4879. (_("range:"), mapRange[0], mapRange[1]))
  4880. def UpdateVolumeIsosurfPage(self, data):
  4881. """Update dialog -- isosurface attributes"""
  4882. #
  4883. # isosurface attributes
  4884. #
  4885. for attrb in ('topo', 'color', 'mask',
  4886. 'transp', 'shine'):
  4887. # skip empty attributes
  4888. if attrb not in data:
  4889. self.SetMapObjUseMap(nvizType='volume', attrb=attrb, map=None)
  4890. continue
  4891. value = data[attrb]['value']
  4892. if attrb == 'color':
  4893. if data[attrb]['map']:
  4894. self.FindWindowById(
  4895. self.win['volume'][attrb]['map']).SetValue(value)
  4896. else: # constant
  4897. color = map(int, value.split(':'))
  4898. self.FindWindowById(
  4899. self.win['volume'][attrb]['const']).SetColour(color)
  4900. else:
  4901. if data[attrb]['map']:
  4902. self.vetoGSelectEvt = True
  4903. win = self.FindWindowById(self.win['volume'][attrb]['map'])
  4904. win.SetValue(value)
  4905. else:
  4906. if value:
  4907. win = self.FindWindowById(
  4908. self.win['volume'][attrb]['const'])
  4909. if attrb == 'topo':
  4910. win.SetValue(float(value))
  4911. else:
  4912. win.SetValue(self._getPercent(value))
  4913. self.SetMapObjUseMap(nvizType='volume',
  4914. attrb=attrb, map=data[attrb]['map'])
  4915. # set inout
  4916. if 'inout' in data:
  4917. self.FindWindowById(
  4918. self.win['volume']['inout']).SetValue(
  4919. data['inout']['value'])
  4920. def UpdateVolumeSlicePage(self, data):
  4921. """Update dialog -- slice attributes"""
  4922. if data:
  4923. for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
  4924. win = self.FindWindowById(
  4925. self.win['volume']['slice'][
  4926. 'slider_' + coord])
  4927. win.Enable()
  4928. win.SetValue(data['position'][coord] * 100)
  4929. win = self.FindWindowById(self.win['volume']['slice']['axes'])
  4930. win.SetSelection(data['position']['axis'])
  4931. win.Enable()
  4932. win = self.FindWindowById(self.win['volume']['slice']['transp'])
  4933. win.SetValue(self._getPercent(data['transp']['value']))
  4934. win.Enable()
  4935. self.FindWindowById(self.win['volume']['slice']['reset']).Enable()
  4936. else:
  4937. for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
  4938. self.FindWindowById(
  4939. self.win['volume']['slice'][
  4940. 'slider_' + coord]).Disable()
  4941. self.FindWindowById(self.win['volume']['slice']['axes']).Disable()
  4942. self.FindWindowById(
  4943. self.win['volume']['slice']['transp']).Disable()
  4944. self.FindWindowById(self.win['volume']['slice']['reset']).Disable()
  4945. self.UpdateSliceLabels()
  4946. def UpdateSliceLabels(self):
  4947. """Update text labels of slice controls according to axis"""
  4948. sel = self.FindWindowById(
  4949. self.win['volume']['slice']['axes']).GetSelection()
  4950. if sel == 0:
  4951. self.FindWindowByName('label_edge_0').SetLabel(_("North edge:"))
  4952. self.FindWindowByName('label_edge_1').SetLabel(_("South edge:"))
  4953. self.FindWindowByName('label_edge_2').SetLabel(_("West edge:"))
  4954. self.FindWindowByName('label_edge_3').SetLabel(_("East edge:"))
  4955. self.FindWindowByName('label_coord_0').SetLabel(_("Northing (Y):"))
  4956. self.FindWindowByName('label_coord_1').SetLabel(_("Height (Z):"))
  4957. self.FindWindowByName('label_coord_2').SetLabel(_("Easting (X):"))
  4958. elif sel == 1:
  4959. self.FindWindowByName('label_edge_0').SetLabel(_("West edge:"))
  4960. self.FindWindowByName('label_edge_1').SetLabel(_("East edge:"))
  4961. self.FindWindowByName('label_edge_2').SetLabel(_("North edge:"))
  4962. self.FindWindowByName('label_edge_3').SetLabel(_("South edge:"))
  4963. self.FindWindowByName('label_coord_0').SetLabel(_("Easting (X):"))
  4964. self.FindWindowByName('label_coord_1').SetLabel(_("Height (Z):"))
  4965. self.FindWindowByName('label_coord_2').SetLabel(_("Northing (Y):"))
  4966. else:
  4967. self.FindWindowByName('label_edge_0').SetLabel(_("West edge:"))
  4968. self.FindWindowByName('label_edge_1').SetLabel(_("East edge:"))
  4969. self.FindWindowByName('label_edge_2').SetLabel(_("Bottom edge:"))
  4970. self.FindWindowByName('label_edge_3').SetLabel(_("Top edge:"))
  4971. self.FindWindowByName('label_coord_0').SetLabel(_("Easting (X):"))
  4972. self.FindWindowByName('label_coord_1').SetLabel(_("Northing (Y):"))
  4973. self.FindWindowByName('label_coord_2').SetLabel(_("Height (Z):"))
  4974. def SetPage(self, name):
  4975. """Get named page"""
  4976. if name == 'view':
  4977. self.SetSelection(0)
  4978. elif name in ('surface', 'vector', 'volume'):
  4979. self.SetSelection(1)
  4980. else:
  4981. self.SetSelection(2)
  4982. win = self.FindWindowById(self.page[name]['notebook'])
  4983. try:
  4984. win.Expand(win.GetFoldPanel(self.page[name]['id']))
  4985. self.UpdateScrolling(
  4986. (win.GetFoldPanel(self.page[name]['id']).GetGrandParent(),))
  4987. except AttributeError:
  4988. win.SetSelection(self.page[name]['id'])
  4989. class PositionWindow(wx.Window):
  4990. """Abstract position control window, see subclasses
  4991. ViewPostionWindow and LightPositionWindow"""
  4992. def __init__(self, parent, mapwindow, id=wx.ID_ANY,
  4993. **kwargs):
  4994. self.mapWindow = mapwindow
  4995. self.quick = True
  4996. wx.Window.__init__(self, parent, id, **kwargs)
  4997. self.SetBackgroundColour("WHITE")
  4998. self.pdc = wx.PseudoDC()
  4999. self.pdc.SetBrush(wx.Brush(colour='dark green', style=wx.SOLID))
  5000. self.pdc.SetPen(wx.Pen(colour='dark green', width=2, style=wx.SOLID))
  5001. self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
  5002. self.Bind(wx.EVT_PAINT, self.OnPaint)
  5003. # self.Bind(wx.EVT_MOTION, self.OnMouse)
  5004. self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
  5005. def Draw(self, pos, scale=False):
  5006. w, h = self.GetClientSize()
  5007. x, y = pos
  5008. if scale:
  5009. x = x * w
  5010. y = y * h
  5011. self.pdc.Clear()
  5012. self.pdc.BeginDrawing()
  5013. self.pdc.DrawLine(w / 2, h / 2, x, y)
  5014. self.pdc.DrawCircle(x, y, 5)
  5015. self.pdc.EndDrawing()
  5016. def OnPaint(self, event):
  5017. dc = wx.BufferedPaintDC(self)
  5018. dc.SetBackground(wx.Brush("White"))
  5019. dc.Clear()
  5020. # probably does nothing, removed from wxPython 2.9
  5021. # self.PrepareDC(dc)
  5022. self.pdc.DrawToDC(dc)
  5023. def UpdatePos(self, xcoord, ycoord):
  5024. """Update position coordinates (origin: UL)"""
  5025. if xcoord < 0.0:
  5026. xcoord = 0.0
  5027. elif xcoord > 1.0:
  5028. xcoord = 1.0
  5029. if ycoord < 0.0:
  5030. ycoord = 0.0
  5031. elif ycoord > 1.0:
  5032. ycoord = 1.0
  5033. x, y = self.TransformCoordinates(xcoord, ycoord)
  5034. self.data['position']['x'] = x
  5035. self.data['position']['y'] = y
  5036. return xcoord, ycoord
  5037. def OnMouse(self, event):
  5038. if event.LeftIsDown():
  5039. x, y = event.GetPosition()
  5040. self.Draw(pos=(x, y))
  5041. w, h = self.GetClientSize()
  5042. x = float(x) / w
  5043. y = float(y) / h
  5044. self.UpdatePos(x, y)
  5045. self.Refresh(False)
  5046. event.Skip()
  5047. def PostDraw(self):
  5048. x, y = self.UpdatePos(self.data['position']['x'],
  5049. self.data['position']['y'])
  5050. self.Draw(pos=(x, y), scale=True)
  5051. class ViewPositionWindow(PositionWindow):
  5052. """View position control widget"""
  5053. def __init__(self, parent, mapwindow, id=wx.ID_ANY,
  5054. **kwargs):
  5055. PositionWindow.__init__(self, parent, mapwindow, id, **kwargs)
  5056. self.SetToolTipString(
  5057. _("Adjusts the distance and direction of the image viewpoint"))
  5058. self.data = self.mapWindow.view
  5059. self.PostDraw()
  5060. def UpdatePos(self, xcoord, ycoord):
  5061. x, y = PositionWindow.UpdatePos(self, xcoord, ycoord)
  5062. event = wxUpdateView(zExag=True)
  5063. wx.PostEvent(self.mapWindow, event)
  5064. return x, y
  5065. def TransformCoordinates(self, x, y, toLight=True):
  5066. return x, y
  5067. def OnMouse(self, event):
  5068. # use focus instead of viewdir
  5069. self.mapWindow.iview['dir']['use'] = False
  5070. PositionWindow.OnMouse(self, event)
  5071. if event.LeftIsDown():
  5072. self.mapWindow.render['quick'] = self.quick
  5073. self.mapWindow.Refresh(eraseBackground=False)
  5074. elif event.LeftUp():
  5075. self.mapWindow.render['quick'] = False
  5076. self.mapWindow.Refresh(eraseBackground=False)
  5077. event.Skip()
  5078. class LightPositionWindow(PositionWindow):
  5079. """Light position control widget"""
  5080. def __init__(self, parent, mapwindow, id=wx.ID_ANY,
  5081. **kwargs):
  5082. PositionWindow.__init__(self, parent, mapwindow, id, **kwargs)
  5083. self.SetToolTipString(_("Adjusts the light direction. "
  5084. "Click and drag the puck to change the light direction."))
  5085. self.data = self.mapWindow.light
  5086. self.quick = False
  5087. self.PostDraw()
  5088. def UpdatePos(self, xcoord, ycoord):
  5089. x, y = PositionWindow.UpdatePos(self, xcoord, ycoord)
  5090. event = wxUpdateLight(refresh=False)
  5091. wx.PostEvent(self.mapWindow, event)
  5092. return x, y
  5093. def TransformCoordinates(self, x, y, toLight=True):
  5094. if toLight:
  5095. x = 2 * x - 1
  5096. y = -2 * y + 1
  5097. else:
  5098. x = (x + 1) / 2
  5099. y = (1 - y) / 2
  5100. return x, y
  5101. def PostDraw(self):
  5102. event = wxUpdateLight(refresh=True)
  5103. wx.PostEvent(self.mapWindow, event)
  5104. x, y = self.data['position']['x'], self.data['position']['y']
  5105. x, y = self.TransformCoordinates(x, y, toLight=False)
  5106. self.Draw(pos=(x, y), scale=True)
  5107. def OnMouse(self, event):
  5108. PositionWindow.OnMouse(self, event)
  5109. if event.LeftUp():
  5110. self.mapWindow.render['quick'] = False
  5111. self.mapWindow.Refresh(eraseBackground=False)