tools.py 229 KB

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