tools.py 227 KB

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