tools.py 227 KB

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