tools.py 227 KB

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