tools.py 231 KB

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